/* ==========================================================================
   Practice Marketplace — catalog, country and listing pages.

   One stylesheet for the whole shop front, built entirely on the site's theme
   tokens (--color-primary, --color-bg-card …) so a tenant re-brand carries
   through without a single override here. Everything is fluid: the grid is
   `auto-fill` rather than fixed breakpoints, so the same markup gives four
   columns on a desktop, two on a tablet and one on a phone with no media
   query deciding it.
   ========================================================================== */

.mk {
  --mk-radius: 16px;
  --mk-radius-lg: 22px;
  --mk-gap: 1.25rem;
  --mk-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 8px 24px rgba(15, 23, 42, .06);
  --mk-shadow-lift: 0 12px 20px rgba(15, 23, 42, .08), 0 28px 48px rgba(15, 23, 42, .12);
}

/* ── Hero ────────────────────────────────────────────────────────────────── */

.mk-hero {
  position: relative;
  overflow: hidden;
  color: var(--color-text-light);
  background:
    radial-gradient(1200px 520px at 82% -20%, rgba(var(--color-secondary-rgb), .28), transparent 62%),
    radial-gradient(900px 460px at -5% 10%, rgba(var(--color-accent-rgb), .16), transparent 58%),
    var(--color-primary);
  border-radius: 0 0 var(--mk-radius-lg) var(--mk-radius-lg);
}
/* A faint grid over the gradient — enough texture that the hero does not read
   as a flat colour block, invisible enough never to compete with the words. */
.mk-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, .06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .06) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(700px 340px at 50% 0%, #000, transparent 75%);
  pointer-events: none;
}
.mk-hero > * { position: relative; z-index: 1; }
.mk-hero h1,
.mk-hero .mk-hero__title { color: var(--color-text-light) !important; font-weight: 800; letter-spacing: -.025em; line-height: 1.06; }
.mk-hero__lead { color: rgba(255, 255, 255, .84); font-size: 1.06rem; max-width: 46rem; }
.mk-hero__eyebrow {
  display: inline-flex; align-items: center; gap: .45rem;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .24);
  color: #fff; border-radius: 999px;
  padding: .35rem .85rem; font-size: .78rem; font-weight: 600;
  letter-spacing: .02em;
}

/* Search bar — the single most-used control on the page, so it gets the
   largest hit area and the strongest contrast in the hero. */
.mk-search {
  display: flex; align-items: center; gap: .5rem;
  background: var(--color-bg-card);
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(15, 23, 42, .22);
  padding: .4rem .4rem .4rem 1rem;
}
.mk-search i { color: var(--color-text-muted); }
.mk-search input {
  flex: 1 1 auto; min-width: 0;
  border: 0; outline: 0; background: transparent;
  font-size: 1rem; color: var(--color-text-dark);
  padding: .6rem 0;
}
.mk-search input::placeholder { color: var(--color-text-muted); }
.mk-search button {
  flex: none; border: 0; border-radius: 11px;
  background: var(--color-primary); color: #fff;
  font-weight: 700; padding: .62rem 1.35rem;
}
.mk-search button:hover { filter: brightness(1.08); }

.mk-hero__stats { display: flex; flex-wrap: wrap; gap: 1.75rem; }
.mk-hero__stat b { display: block; font-size: 1.55rem; font-weight: 800; line-height: 1; }
.mk-hero__stat span { font-size: .8rem; color: rgba(255, 255, 255, .72); text-transform: uppercase; letter-spacing: .06em; }

/* ── Hero showcase ──────────────────────────────────────────────────────
   The products, rotating, in the space the hero was wasting. Each slide is a
   whole link: artwork, what it is, and the two numbers that decide whether it
   is worth opening. Slides cross-fade in place (no horizontal motion) so the
   hero never jitters the text next to it, and the artwork is CONTAINED — a
   cover cropped by its own shop window is worse than a letterbox.            */
.mk-showcase {
  --mk-showcase-radius: 20px;
  position: relative;
}
.mk-showcase__stage {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  border-radius: var(--mk-showcase-radius);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .07);
  box-shadow: 0 30px 60px rgba(2, 6, 23, .42);
  /* Sits slightly out of the page plane so it reads as an object in front of
     the hero rather than a panel painted onto it. */
  transform: perspective(1400px) rotateY(-6deg) rotateX(2deg);
  transition: transform .5s cubic-bezier(.22, .8, .3, 1);
}
.mk-showcase:hover .mk-showcase__stage,
.mk-showcase:focus-within .mk-showcase__stage {
  transform: perspective(1400px) rotateY(0deg) rotateX(0deg);
}
.mk-showcase__slide {
  position: absolute; inset: 0;
  display: block; text-decoration: none; color: #fff;
  opacity: 0; visibility: hidden;
  transform: scale(1.04);
  transition: opacity .7s ease, transform 7s linear, visibility 0s linear .7s;
}
.mk-showcase__slide.is-active {
  opacity: 1; visibility: visible;
  transform: scale(1);
  transition: opacity .7s ease, transform 7s linear, visibility 0s;
}
.mk-showcase__wash {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.25); filter: blur(30px) saturate(1.35); opacity: .6;
}
.mk-showcase__art {
  position: absolute; inset: 0;
  /* Contained, not cropped: these are designed covers with titles on them, and
     a shop window that cuts the title off sells nothing. The blurred copy
     behind fills whatever letterbox a non-4:3 cover leaves. */
  width: 100%; height: 100%; object-fit: contain;
}
.mk-showcase__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(2, 6, 23, .94) 0%, rgba(2, 6, 23, .6) 32%, rgba(2, 6, 23, 0) 60%);
  pointer-events: none;
}
.mk-showcase__meta {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column; gap: .4rem;
  padding: 1.1rem 1.15rem;
}
.mk-showcase__tags { display: flex; flex-wrap: wrap; gap: .35rem; }
.mk-showcase__tag {
  background: rgba(255, 255, 255, .18);
  border: 1px solid rgba(255, 255, 255, .26);
  border-radius: 999px; padding: .18rem .6rem;
  font-size: .72rem; font-weight: 600; color: #fff;
  backdrop-filter: blur(6px);
}
.mk-showcase__tag--free {
  background: rgba(16, 185, 129, .28); border-color: rgba(16, 185, 129, .5);
}
.mk-showcase__title {
  font-size: 1.06rem; font-weight: 800; line-height: 1.25; color: #fff;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.mk-showcase__facts { font-size: .8rem; color: rgba(255, 255, 255, .78); }

.mk-showcase__dots {
  display: flex; gap: .4rem; justify-content: center;
  margin-top: .85rem;
}
.mk-showcase__dot {
  border: 0; background: transparent; padding: .35rem .2rem;
  cursor: pointer; line-height: 0;
}
.mk-showcase__dot i {
  display: block; width: 26px; height: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .3);
  transition: background .25s, width .25s;
}
.mk-showcase__dot.is-active i { background: #fff; width: 40px; }
.mk-showcase__dot:focus-visible i { outline: 2px solid #fff; outline-offset: 3px; }

@media (max-width: 991.98px) {
  .mk-showcase { margin-top: 1.5rem; }
  .mk-showcase__stage { transform: none; aspect-ratio: 16 / 10; }
}

/* Motion is decoration here: with it suppressed the showcase becomes a plain
   still of the first listing, and the dots still switch it. */
@media (prefers-reduced-motion: reduce) {
  .mk-showcase__stage,
  .mk-showcase__slide { transition: none; transform: none; }
  .mk-showcase:hover .mk-showcase__stage { transform: none; }
}

/* Quick chips under the search: the three or four searches most people
   actually want, one tap away. */
.mk-chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.mk-chip {
  display: inline-flex; align-items: center; gap: .4rem;
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .22);
  color: #fff; border-radius: 999px;
  padding: .38rem .85rem; font-size: .84rem; text-decoration: none;
  transition: background .15s, transform .15s;
}
.mk-chip:hover { background: rgba(255, 255, 255, .24); color: #fff; transform: translateY(-1px); }

/* ── Layout: filter rail + results ───────────────────────────────────────── */

.mk-layout { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 2rem; align-items: start; }
@media (max-width: 991.98px) { .mk-layout { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; } }

.mk-rail { position: sticky; top: 1.5rem; }
.mk-rail__toggle { display: none; }
@media (max-width: 991.98px) {
  .mk-rail { position: static; }
  /* On a phone the rail is a wall between the visitor and the products, so it
     folds behind one button. The button is script-driven (see catalog.html):
     without JavaScript it never appears and the panel stays open, because a
     hidden filter panel with no way to open it is worse than a long one. */
  .mk-rail__toggle {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; gap: .5rem;
    background: var(--color-bg-card); border: 1px solid var(--color-border);
    border-radius: var(--mk-radius); box-shadow: var(--mk-shadow);
    padding: .8rem 1.1rem; font-weight: 700; font-size: .9rem;
    color: var(--color-text-heading);
  }
  .mk-rail__toggle i.fa-chevron-down { transition: transform .18s; font-size: .72rem; color: var(--color-text-muted); }
  .mk-rail__toggle[aria-expanded="false"] i.fa-chevron-down { transform: rotate(-90deg); }
  .mk-rail__toggle[aria-expanded="false"] + .mk-panel { display: none; }
  .mk-rail__toggle[aria-expanded="true"] + .mk-panel { margin-top: .6rem; }
  /* The toggle already says "Filters"; the panel's own header would say it
     twice, so only "Clear all" survives there. */
  .mk-rail__head strong { display: none; }
  .mk-rail__head > div { justify-content: flex-end !important; }
}

.mk-panel {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--mk-radius);
  box-shadow: var(--mk-shadow);
}

.mk-filter { border-bottom: 1px solid var(--color-border-light); padding: .95rem 1.1rem; }
.mk-filter:last-child { border-bottom: 0; }
.mk-filter > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  font-weight: 700; font-size: .82rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-text-heading);
}
.mk-filter > summary::-webkit-details-marker { display: none; }
.mk-filter > summary::after {
  content: "\f078"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  font-size: .68rem; color: var(--color-text-muted); transition: transform .18s;
}
.mk-filter[open] > summary::after { transform: rotate(180deg); }
.mk-filter__options { margin-top: .7rem; display: flex; flex-direction: column; gap: .1rem; max-height: 15rem; overflow-y: auto; }

.mk-opt {
  display: flex; align-items: center; gap: .55rem;
  padding: .34rem .4rem; border-radius: 8px;
  font-size: .88rem; color: var(--color-text-secondary);
  cursor: pointer; transition: background .12s;
}
.mk-opt:hover { background: var(--color-bg-muted); }
.mk-opt input { accent-color: var(--color-primary); flex: none; margin: 0; }
.mk-opt__label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mk-opt__count { flex: none; font-size: .75rem; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.mk-opt input:checked ~ .mk-opt__label { color: var(--color-text-heading); font-weight: 600; }

/* ── Toolbar ─────────────────────────────────────────────────────────────── */

.mk-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .75rem; margin-bottom: 1.1rem;
}
.mk-toolbar__count { font-size: .92rem; color: var(--color-text-secondary); }
.mk-toolbar__count strong { color: var(--color-text-heading); }
.mk-sort {
  border: 1px solid var(--color-border); border-radius: 10px;
  background: var(--color-bg-card); color: var(--color-text-dark);
  padding: .45rem 2rem .45rem .75rem; font-size: .88rem;
}

/* Applied filters, as removable pills — the only honest way to show a shopper
   what is currently narrowing their results. */
.mk-applied { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1rem; }
.mk-applied__pill {
  display: inline-flex; align-items: center; gap: .45rem;
  background: rgba(var(--color-primary-rgb), .08);
  color: var(--color-primary);
  border: 1px solid rgba(var(--color-primary-rgb), .18);
  border-radius: 999px; padding: .28rem .75rem;
  font-size: .8rem; font-weight: 600; text-decoration: none;
}
.mk-applied__pill:hover { background: rgba(var(--color-primary-rgb), .16); color: var(--color-primary); }
/* The quieter of two actions on one row. A learner with an attempt still to
   spend gets both Start and Review; Start is the one being offered, so Review
   steps back rather than competing with it. */
.mk-applied__pill--ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: var(--color-border);
}
.mk-applied__pill--ghost:hover {
  background: var(--color-bg-muted);
  color: var(--color-text-heading);
}
.mk-applied__clear { font-size: .8rem; color: var(--color-text-muted); text-decoration: underline; align-self: center; }

/* ── The grid ────────────────────────────────────────────────────────────── */

.mk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: var(--mk-gap);
}
.mk-grid--wide { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }

.mk-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--mk-radius);
  box-shadow: var(--mk-shadow);
  overflow: hidden;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  height: 100%;
}
.mk-card:hover { transform: translateY(-4px); box-shadow: var(--mk-shadow-lift); border-color: var(--color-border-primary); }
.mk-card__link { display: flex; flex-direction: column; height: 100%; text-decoration: none; color: inherit; }

.mk-card__media { position: relative; aspect-ratio: 16 / 9; background: var(--color-bg-muted); overflow: hidden; }
.mk-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
.mk-card:hover .mk-card__media img { transform: scale(1.045); }

/* The generated cover for a listing with no artwork yet. It uses the brand
   gradient and the exam's own name, so an un-illustrated listing still looks
   deliberate in a grid next to designed thumbnails. */
.mk-card__fallback {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; padding: 1rem; text-align: center;
  background:
    radial-gradient(420px 200px at 80% 0%, rgba(var(--color-secondary-rgb), .28), transparent 65%),
    linear-gradient(135deg, var(--color-primary), color-mix(in srgb, var(--color-primary) 62%, var(--color-secondary)));
}
.mk-card__fallback-flag { font-size: 2.1rem; line-height: 1; }
.mk-card__fallback-title { color: rgba(255, 255, 255, .95); font-weight: 700; font-size: .92rem; line-height: 1.25; }

.mk-card__flags { position: absolute; top: .6rem; left: .6rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.mk-flag {
  display: inline-flex; align-items: center; gap: .3rem;
  border-radius: 7px; padding: .22rem .5rem;
  font-size: .7rem; font-weight: 700; letter-spacing: .02em;
  backdrop-filter: blur(6px);
}
.mk-flag--free { background: var(--color-success); color: #fff; }
.mk-flag--deal { background: var(--color-accent); color: var(--color-primary); }
.mk-flag--try { background: rgba(15, 23, 42, .62); color: #fff; }

.mk-card__official {
  position: absolute; bottom: .6rem; right: .6rem;
  display: inline-flex; align-items: center; gap: .3rem;
  background: rgba(255, 255, 255, .94); color: var(--color-primary);
  border-radius: 7px; padding: .2rem .5rem;
  font-size: .68rem; font-weight: 700;
}

.mk-card__body { display: flex; flex-direction: column; gap: .55rem; padding: .95rem 1rem 1.05rem; flex: 1 1 auto; }
.mk-card__tags { display: flex; flex-wrap: wrap; gap: .3rem; }
.mk-tag {
  background: var(--color-bg-muted); color: var(--color-text-secondary);
  border-radius: 6px; padding: .16rem .45rem;
  font-size: .7rem; font-weight: 600; white-space: nowrap;
}
.mk-tag--level { background: rgba(var(--color-primary-rgb), .1); color: var(--color-primary); }
.mk-tag--place { background: transparent; padding-left: 0; }

.mk-card__title {
  margin: 0; font-size: 1rem; font-weight: 700; line-height: 1.34;
  color: var(--color-text-heading);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.mk-card__summary { margin: 0; font-size: .84rem; line-height: 1.45; color: var(--color-text-muted); }

.mk-card__rating { display: flex; align-items: center; gap: .35rem; font-size: .82rem; }
.mk-card__rating strong { color: var(--color-text-heading); }
.mk-stars { color: #f59e0b; font-size: .74rem; letter-spacing: .5px; }
.mk-stars .fa-regular { color: var(--color-border); }
.mk-card__rating-count { color: var(--color-text-muted); font-size: .78rem; }

.mk-card__stats { display: flex; flex-wrap: wrap; gap: .75rem; margin: 0; padding: 0; list-style: none; }
.mk-card__stats li { display: inline-flex; align-items: center; gap: .3rem; font-size: .78rem; color: var(--color-text-muted); }
.mk-card__stats i { font-size: .72rem; opacity: .8; }

.mk-card__foot {
  margin-top: auto; padding-top: .7rem;
  border-top: 1px solid var(--color-border-light);
  display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
}
.mk-price { font-weight: 800; font-size: 1.02rem; color: var(--color-text-heading); }
.mk-price s { font-weight: 600; font-size: .8rem; color: var(--color-text-muted); margin-left: .3rem; }
.mk-price--free { color: var(--color-success); }
.mk-card__cta { display: inline-flex; align-items: center; gap: .35rem; font-size: .84rem; font-weight: 700; color: var(--color-primary); }
.mk-card:hover .mk-card__cta i { transform: translateX(3px); }
.mk-card__cta i { transition: transform .18s; }

/* ── Empty state ─────────────────────────────────────────────────────────── */

.mk-empty { text-align: center; padding: 3.5rem 1.5rem; }
.mk-empty__icon { font-size: 2.4rem; color: var(--color-border); margin-bottom: .75rem; }
.mk-empty h3 { font-size: 1.05rem; font-weight: 700; color: var(--color-text-heading); }
.mk-empty p { color: var(--color-text-muted); }

/* ── Browse rails (country tiles, bundles) ───────────────────────────────── */

.mk-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1.1rem; }
.mk-section-head h2 { margin: 0; font-size: 1.22rem; font-weight: 800; letter-spacing: -.01em; color: var(--color-text-heading); }
.mk-section-head p { margin: .2rem 0 0; font-size: .88rem; color: var(--color-text-muted); }
.mk-section-head a { font-size: .86rem; font-weight: 700; color: var(--color-primary); text-decoration: none; white-space: nowrap; }

.mk-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: .85rem; }
.mk-tile {
  display: flex; align-items: center; gap: .7rem;
  background: var(--color-bg-card); border: 1px solid var(--color-border);
  border-radius: 13px; padding: .8rem .9rem; text-decoration: none;
  transition: transform .15s, border-color .15s, box-shadow .15s;
}
.mk-tile:hover { transform: translateY(-2px); border-color: var(--color-border-primary); box-shadow: var(--mk-shadow); }
.mk-tile__flag { font-size: 1.6rem; line-height: 1; }
.mk-tile__name { font-weight: 700; font-size: .9rem; color: var(--color-text-heading); }
.mk-tile__count { font-size: .76rem; color: var(--color-text-muted); }

/* ── Listing (detail) page ───────────────────────────────────────────────── */

.mk-detail-hero {
  position: relative; overflow: hidden; color: #fff;
  background:
    radial-gradient(1100px 460px at 88% -25%, rgba(var(--color-secondary-rgb), .32), transparent 62%),
    radial-gradient(720px 380px at -5% 115%, rgba(var(--color-accent-rgb), .16), transparent 58%),
    linear-gradient(135deg, var(--color-primary), color-mix(in srgb, var(--color-primary) 68%, var(--color-secondary)));
  border-radius: 0 0 var(--mk-radius-lg) var(--mk-radius-lg);
}
.mk-detail-hero h1, .mk-detail-hero h2, .mk-detail-hero a { color: #fff !important; }
.mk-detail-hero h1 { font-weight: 800; letter-spacing: -.02em; line-height: 1.12; }
.mk-crumbs { font-size: .84rem; color: rgba(255, 255, 255, .75); }
.mk-crumbs a { color: rgba(255, 255, 255, .82) !important; text-decoration: none; }
.mk-crumbs a:hover { color: #fff !important; text-decoration: underline; }
.mk-hero-lead { color: rgba(255, 255, 255, .86); font-size: 1.02rem; }
.mk-hero-badges { display: flex; flex-wrap: wrap; gap: .4rem; }
.mk-hero-badge {
  display: inline-flex; align-items: center; gap: .35rem;
  background: rgba(255, 255, 255, .15); border: 1px solid rgba(255, 255, 255, .24);
  color: #fff; border-radius: 999px; padding: .28rem .75rem;
  font-size: .76rem; font-weight: 600;
}
.mk-hero-cover {
  width: 100%; border-radius: var(--mk-radius);
  box-shadow: 0 22px 48px rgba(0, 0, 0, .3);
  border: 1px solid rgba(255, 255, 255, .2);
  aspect-ratio: 16 / 10; object-fit: cover;
}

/* The listing's artwork. Covers are authored in whatever shape the designer
   chose, so cropping them to the frame cut the title straight off the poster.
   The frame keeps its fixed 16/10 footprint (every listing page lines up), and
   the artwork is CONTAINED inside it — the whole image, always. The letterbox
   left over is filled with a blurred, scaled copy of the same artwork, so the
   frame still reads as one solid object rather than a picture floating on a
   grey slab. */
.mk-hero-art {
  position: relative; width: 100%; aspect-ratio: 16 / 10;
  border-radius: var(--mk-radius); overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .2);
  box-shadow: 0 22px 48px rgba(0, 0, 0, .3);
  background: rgba(255, 255, 255, .07);
}
.mk-hero-art__wash {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transform: scale(1.2);
  filter: blur(28px) saturate(1.3); opacity: .55;
}
.mk-hero-art__img {
  position: relative; width: 100%; height: 100%;
  object-fit: contain; display: block;
}
.mk-hero-cover--blank {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .55rem; padding: 1.5rem; text-align: center;
  background: rgba(255, 255, 255, .09);
  backdrop-filter: blur(2px);
}
.mk-hero-cover__flag { font-size: 2.6rem; line-height: 1; }
.mk-hero-cover__title { font-weight: 700; font-size: 1.05rem; color: #fff; line-height: 1.3; }
.mk-hero-cover__meta { font-size: .82rem; color: rgba(255, 255, 255, .78); letter-spacing: .04em; text-transform: uppercase; }

/* The stat strip that overlaps the hero — it belongs to both, which is what
   makes the page read as one object instead of two stacked sections. */
.mk-statstrip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px; background: var(--color-border);
  border: 1px solid var(--color-border); border-radius: var(--mk-radius);
  overflow: hidden; box-shadow: var(--mk-shadow);
}
.mk-stat { background: var(--color-bg-card); padding: 1rem .75rem; text-align: center; }
.mk-stat b { display: block; font-size: 1.3rem; font-weight: 800; color: var(--color-text-heading); line-height: 1.15; }
.mk-stat span { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--color-text-muted); }

.mk-block { background: var(--color-bg-card); border: 1px solid var(--color-border); border-radius: var(--mk-radius); box-shadow: var(--mk-shadow); }
.mk-block__head { padding: 1.1rem 1.25rem .35rem; }
.mk-block__head h2 { margin: 0; font-size: 1.05rem; font-weight: 800; color: var(--color-text-heading); }
.mk-block__head p { margin: .25rem 0 0; font-size: .86rem; color: var(--color-text-muted); }
.mk-block__body { padding: .5rem 1.25rem 1.15rem; }
.mk-prose { color: var(--color-text-secondary); font-size: .93rem; line-height: 1.65; white-space: pre-line; }

/* A "way to practise" row: icon, name, one line of what it is, one action. */
.mk-mode { display: flex; align-items: center; gap: .9rem; padding: .85rem 0; border-bottom: 1px solid var(--color-border-light); }
.mk-mode:last-child { border-bottom: 0; }
.mk-mode__icon {
  flex: none; width: 40px; height: 40px; border-radius: 11px;
  display: grid; place-items: center;
  background: rgba(var(--color-primary-rgb), .09); color: var(--color-primary);
}
.mk-mode__text { flex: 1 1 auto; min-width: 0; }
.mk-mode__name { font-weight: 700; font-size: .93rem; color: var(--color-text-heading); display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.mk-mode__desc { font-size: .82rem; color: var(--color-text-muted); }
.mk-mode__action { flex: none; }
.mk-pill { border-radius: 999px; padding: .12rem .5rem; font-size: .66rem; font-weight: 700; letter-spacing: .02em; }
.mk-pill--free { background: rgba(16, 185, 129, .13); color: var(--color-success); }
.mk-pill--premium { background: rgba(var(--color-primary-rgb), .1); color: var(--color-primary); }
.mk-pill--new { background: rgba(var(--color-secondary-rgb), .14); color: var(--color-secondary); }

/* Buy card — sticky on desktop because the decision it holds is the reason
   the page exists. */
.mk-buy {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-primary);
  border-radius: var(--mk-radius-lg);
  box-shadow: var(--mk-shadow-lift);
  overflow: hidden;
}
.mk-buy__inner { padding: 1.35rem; }
.mk-buy__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem; font-size: 2.05rem; font-weight: 800; color: var(--color-text-heading); line-height: 1.1; }
.mk-buy__price s { font-size: 1rem; font-weight: 600; color: var(--color-text-muted); }
.mk-buy__period { font-size: .9rem; font-weight: 600; color: var(--color-text-muted); }
.mk-buy__save { display: inline-flex; align-items: center; gap: .35rem; background: rgba(16, 185, 129, .13); color: var(--color-success); border-radius: 999px; padding: .22rem .65rem; font-size: .76rem; font-weight: 700; }
.mk-buy__deadline { font-size: .8rem; color: var(--color-danger); font-weight: 600; }
.mk-buy__list { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .55rem; }
.mk-buy__list li { display: flex; gap: .55rem; font-size: .87rem; color: var(--color-text-secondary); line-height: 1.4; }
.mk-buy__list i { color: var(--color-success); margin-top: .18rem; flex: none; }
.mk-btn {
  display: flex; align-items: center; justify-content: center; gap: .45rem;
  width: 100%; border: 0; border-radius: 12px;
  padding: .85rem 1rem; font-weight: 700; font-size: .98rem;
  text-decoration: none; transition: filter .15s, transform .15s;
}
.mk-btn:hover { filter: brightness(1.06); transform: translateY(-1px); }
.mk-btn--primary { background: var(--color-primary); color: #fff; }
.mk-btn--primary:hover { color: #fff; }
.mk-btn--free { background: var(--color-success); color: #fff; }
.mk-btn--free:hover { color: #fff; }
.mk-btn--accent { background: var(--color-accent); color: var(--color-primary); }
.mk-btn--accent:hover { color: var(--color-primary); }
.mk-btn--owned { background: rgba(16, 185, 129, .12); color: var(--color-success); border: 1px solid color-mix(in srgb, var(--color-success) 35%, transparent); }
.mk-buy__note { margin: .6rem 0 0; text-align: center; font-size: .78rem; color: var(--color-text-muted); }

/* Try-free banner: the highest-converting element on the page, so it is the
   one thing above the description that is allowed to shout. */
.mk-try {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
  border-radius: var(--mk-radius); padding: 1.15rem 1.3rem;
  background:
    radial-gradient(520px 200px at 88% 0%, rgba(var(--color-accent-rgb), .22), transparent 70%),
    var(--color-bg-hero);
  border: 1px solid var(--color-border-primary);
}
.mk-try h2 { margin: 0 0 .2rem; font-size: 1.02rem; font-weight: 800; color: var(--color-text-heading); }
.mk-try p { margin: 0; font-size: .86rem; color: var(--color-text-secondary); max-width: 34rem; }
.mk-try .mk-btn { width: auto; }
.mk-try__actions { display: flex; flex-wrap: wrap; gap: .5rem; }

/* Start and Review sit side by side on a mock's row, and wrap under it on a
   narrow screen rather than squeezing the title. */
.mk-mode__actions { display: inline-flex; flex-wrap: wrap; gap: .4rem; align-items: center; }

/* Reviews */
.mk-rating-big { font-size: 2.9rem; font-weight: 800; line-height: 1; color: var(--color-text-heading); }
.mk-bar { height: 7px; border-radius: 6px; background: var(--color-border-light); overflow: hidden; }
.mk-bar > span { display: block; height: 100%; background: #f59e0b; }
.mk-review { display: flex; gap: .9rem; padding: 1rem 0; border-bottom: 1px solid var(--color-border-light); }
.mk-review:last-child { border-bottom: 0; }
.mk-avatar { flex: none; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; background: var(--color-primary); color: #fff; font-weight: 700; }
.mk-star-input { cursor: pointer; font-size: 1.45rem; color: var(--color-border); transition: color .12s; }
.mk-star-input.active { color: #f59e0b; }

/* Included-with-this-package groups.
   A package can carry twenty mock tests; its course and its flashcards must
   still be findable in one glance, so each kind gets a labelled group, the
   chips jump to one, and a long mock list folds after the first six. */
/* Wrapping, not scrolling: on a phone a chip parked off the right edge is a
   chip nobody taps, which is the problem this row exists to solve. */
.mk-jump { display: flex; flex-wrap: wrap; gap: .4rem; margin: .75rem 0 .1rem; }
.mk-jump__chip {
  flex: none;
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .35rem .7rem; border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-bg-card);
  font-size: .8rem; font-weight: 700; text-decoration: none;
  color: var(--color-text-secondary);
  transition: border-color .15s, color .15s, background .15s;
}
.mk-jump__chip:hover,
.mk-jump__chip:focus-visible {
  color: var(--color-primary);
  border-color: var(--color-border-primary);
  background: rgba(var(--color-primary-rgb), .06);
}
.mk-jump__chip i { font-size: .78rem; }
.mk-jump__count {
  background: rgba(var(--color-primary-rgb), .12); color: var(--color-primary);
  border-radius: 999px; padding: 0 .38rem; font-size: .72rem; line-height: 1.5;
}

.mk-group { scroll-margin-top: 5rem; }
.mk-group + .mk-group { margin-top: .35rem; }
.mk-group__head {
  display: flex; align-items: center; gap: .45rem;
  margin: .9rem 0 0; padding-top: .85rem;
  border-top: 1px solid var(--color-border-light);
  font-size: .76rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text-muted);
}
.mk-group:first-child .mk-group__head { margin-top: .25rem; padding-top: 0; border-top: 0; }
.mk-group__head i { color: var(--color-primary); font-size: .82rem; }
.mk-group__count {
  background: var(--color-border-light); color: var(--color-text-secondary);
  border-radius: 999px; padding: 0 .4rem; letter-spacing: 0;
}

.mk-more > summary { list-style: none; }
.mk-more > summary::-webkit-details-marker { display: none; }
.mk-more__toggle {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: .75rem; padding: .45rem .9rem; border-radius: 999px;
  border: 1px dashed var(--color-border);
  font-size: .82rem; font-weight: 700; color: var(--color-primary);
  cursor: pointer;
}
.mk-more__toggle:hover { background: rgba(var(--color-primary-rgb), .06); }
.mk-more[open] .mk-more__open,
.mk-more:not([open]) .mk-more__close { display: none; }
.mk-more .mk-mode:first-of-type { border-top: 1px solid var(--color-border-light); margin-top: .5rem; }

/* ── Mobile buy bar ───────────────────────────────────────────────────────
   The buy panel is the last column in the grid, so on a phone it sits below
   the whole page: the mock-test list, the courses, the reviews. A visitor who
   decided to buy in the first ten seconds had to scroll past all of it to find
   out how, and the inline "Unlock" pills only jump to #buy — which on a small
   screen looks like the page moved for no reason. The client-analytics
   diagnostic for 2026-08-07 → 2026-09-06 recorded 29 mobile visits, 93.1% of
   them bouncing, and not one checkout from any device.

   This keeps the price and one action on screen the whole way down, the same
   pattern the course pages already use. It is hidden from lg up, where the
   sticky sidebar is already doing the job. */
.mk-buybar { display: none; }
@media (max-width: 991.98px) {
  .mk-buybar {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1030;
    display: flex; align-items: center; gap: .85rem;
    padding: .7rem .9rem;
    padding-bottom: calc(.7rem + env(safe-area-inset-bottom, 0px));
    background: var(--color-bg-card);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -6px 24px rgba(0, 0, 0, .10);
  }
  .mk-buybar__price {
    display: flex; flex-direction: column; line-height: 1.15; flex: none;
  }
  .mk-buybar__price b {
    font-size: 1.15rem; font-weight: 800; color: var(--color-text-heading);
  }
  .mk-buybar__price s { font-size: .75rem; color: var(--color-text-muted); }
  .mk-buybar__price span {
    font-size: .68rem; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--color-text-muted);
  }
  .mk-buybar__action { flex: 1; min-width: 0; }
  /* The bar is a fixed overlay, so the last of the page would otherwise sit
     underneath it — including the "post a review" button. */
  .mk-buybar__action .mk-btn { margin: 0; width: 100%; }
  body.has-mk-buybar { padding-bottom: 84px; }
}

/* ── Mock-test grid ───────────────────────────────────────────────────────
   A package can publish sixty mock tests. As a list of rows, each one read
   "Code de la route (French) — Mock Test 41  ·  Proctored and timed, with a
   certificate when you pass." — the same twelve words sixty times, with the
   only distinguishing character buried at the end of the longest line. Half
   of them were then hidden behind a "show 54 more" fold, so the page a buyer
   lives in after paying could not answer "which ones have I done?" at all.

   The grid answers that in one look: a tile per test carrying its number in
   large type, colour-coded by state, with the same Start/Unlock and Review
   actions the rows had. Repeated text appears once, in the section header. */
/* Sticky, because the grid is taller than the viewport the moment a package
   publishes more than about thirty tests. At 120 a learner who scrolls to test
   100 has left the progress, the filters and the number box a full screen
   behind them — the controls are useless exactly when the list is long enough
   to need them. Pinning the bar is what makes the design hold at any count:
   the way to reach test 87 travels with you.

   Nothing else on this page is fixed-position, so there is no header to offset
   against; ``top: 0`` is the viewport top. */
.mk-tests__bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  margin: .25rem 0 1rem;
  padding: .5rem 0;
  background: var(--color-bg-card);
  border-bottom: 1px solid var(--color-border-light);
}
.mk-tests__progress {
  display: flex; align-items: center; gap: .55rem;
  font-size: .82rem; font-weight: 700; color: var(--color-text-secondary);
  margin-right: auto;
}
.mk-tests__track {
  width: 92px; height: 7px; border-radius: 999px;
  background: var(--color-border-light); overflow: hidden;
}
.mk-tests__track > span {
  display: block; height: 100%; border-radius: 999px;
  background: var(--color-success); transition: width .4s ease;
}

/* Filter chips. A radio group under the hood, so the whole thing works with
   the keyboard and needs no JavaScript to be operable. */
.mk-tests__filters { display: flex; flex-wrap: wrap; gap: .4rem; }
.mk-tests__filter { position: absolute; opacity: 0; pointer-events: none; }
.mk-tests__chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .34rem .72rem; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--color-border);
  background: var(--color-bg-card); color: var(--color-text-secondary);
  font-size: .78rem; font-weight: 700; white-space: nowrap;
  transition: background .14s, color .14s, border-color .14s;
}
.mk-tests__chip:hover { border-color: var(--color-border-primary); }
.mk-tests__filter:checked + .mk-tests__chip {
  background: var(--color-primary); border-color: var(--color-primary); color: #fff;
}
.mk-tests__filter:focus-visible + .mk-tests__chip {
  outline: 2px solid var(--color-primary); outline-offset: 2px;
}
.mk-tests__chip b { font-weight: 800; }

.mk-tests__search {
  flex: none; width: 128px; padding: .34rem .7rem;
  border: 1px solid var(--color-border); border-radius: 999px;
  background: var(--color-bg-card); color: var(--color-text-heading);
  font-size: .78rem;
}

/* The grid itself. auto-fill keeps tiles a readable size at every width
   instead of stretching four of them across a desktop. */
.mk-tests__grid {
  display: grid; gap: .55rem;
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr));
}
.mk-test {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: .35rem; padding: .75rem .5rem .6rem;
  border: 1px solid var(--color-border); border-radius: 14px;
  background: var(--color-bg-card);
  transition: transform .14s, box-shadow .14s, border-color .14s;
}
.mk-test:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.mk-test__num {
  font-size: 1.55rem; font-weight: 800; line-height: 1;
  color: var(--color-text-heading); font-variant-numeric: tabular-nums;
}
.mk-test__caption {
  font-size: .72rem; font-weight: 600; line-height: 1.25; text-align: center;
  color: var(--color-text-secondary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.mk-test__state {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .66rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; padding: .12rem .45rem; border-radius: 999px;
}
.mk-test__actions {
  display: flex; gap: .3rem; width: 100%; margin-top: .15rem;
}
.mk-test__btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  gap: .25rem; padding: .34rem .3rem; border-radius: 8px;
  font-size: .72rem; font-weight: 800; text-decoration: none;
  border: 1px solid transparent; white-space: nowrap;
}
.mk-test__btn--go { background: var(--color-primary); color: #fff; }
.mk-test__btn--go:hover { color: #fff; filter: brightness(1.07); }
.mk-test__btn--ghost {
  background: transparent; color: var(--color-text-secondary);
  border-color: var(--color-border);
}
.mk-test__btn--ghost:hover { background: var(--color-bg-muted); color: var(--color-text-heading); }
.mk-test__btn--lock { background: var(--color-bg-muted); color: var(--color-text-secondary); }
.mk-test__btn--lock:hover { background: var(--color-primary); color: #fff; }

/* State colouring: a border and a chip, so the grid is readable at a glance
   and never *only* by colour — each tile also carries a worded chip. */
.mk-test--done { border-color: color-mix(in srgb, var(--color-success) 45%, var(--color-border)); }
.mk-test--done .mk-test__state { background: color-mix(in srgb, var(--color-success) 15%, transparent); color: var(--color-success); }
.mk-test--done .mk-test__num { color: var(--color-success); }
.mk-test--resume { border-color: color-mix(in srgb, var(--color-warning) 55%, var(--color-border)); }
.mk-test--resume .mk-test__state { background: color-mix(in srgb, var(--color-warning) 18%, transparent); color: var(--color-warning); }
.mk-test--new .mk-test__state { background: var(--color-bg-muted); color: var(--color-text-muted); }
.mk-test--locked { background: var(--color-bg-muted); }
.mk-test--locked .mk-test__num { color: var(--color-text-muted); }
.mk-test--locked .mk-test__state { background: transparent; color: var(--color-text-muted); }

/* Filtering and the number search are done by toggling this class, so the
   grid never reflows through JavaScript-built markup. */
.mk-test.is-hidden { display: none; }
.mk-tests__empty {
  grid-column: 1 / -1; text-align: center; padding: 1.5rem .5rem;
  color: var(--color-text-muted); font-size: .85rem;
}

/* Phones. Sixty tiles two-across is a seven-thousand-pixel scroll, which
   trades one bad experience for another — so the tile loses its padding and
   its button labels shorten to icons, and three or four fit across a phone.
   The actions stay full-size touch targets; only the words go. */
@media (max-width: 575.98px) {
  .mk-tests__grid {
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
    gap: .4rem;
  }
  .mk-test { padding: .5rem .25rem .45rem; gap: .25rem; border-radius: 11px; }
  .mk-test__num { font-size: 1.3rem; }
  .mk-test__state { font-size: .58rem; padding: .1rem .3rem; }
  .mk-test__caption { font-size: .65rem; -webkit-line-clamp: 1; }
  .mk-test__actions { gap: .2rem; }
  .mk-test__btn { padding: .32rem .2rem; font-size: .66rem; min-height: 30px; }
  /* The icon goes, the word stays. The other way round is tempting — an icon
     is smaller — but it leaves a blank button the moment the icon font fails
     to load, and "Start" and "Review" both fit a 118px tile at this size. */
  .mk-test__btn > i { display: none; }
  .mk-tests__search { width: 100%; }
  .mk-tests__bar { gap: .45rem; }
}
