/* ============================================================
   Java Mastery Academy — public site components
   ------------------------------------------------------------
   Port of the java-mastery.com design. Every selector is prefixed
   `jm-` and every colour comes from theme.css tokens, so the same
   markup renders the dark (live-site) and light themes.
   Scoped to body.jm-site → inert on dashboard layouts.
   ============================================================ */

/* ---------- base ---------- */
body.jm-site {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-ui);
    font-size: 16px;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}
[dir="rtl"] body.jm-site,
body.jm-site input,
body.jm-site button,
body.jm-site select,
body.jm-site textarea {
    font-family: var(--font-ui);
}
body.jm-site ::selection { background: rgba(249, 161, 27, .35); color: #fff; }

/* ---------- Arabic typography ----------
   Arabic glyphs are drawn joined, so tracking and uppercasing are meaningless at
   best and break the shaping at worst; the script also needs more leading than
   Latin. These are deliberately last in the base block so a component's own
   letter-spacing (a small-caps label, say) still applies to Latin-only text by
   carrying .jm-track. */
[dir="rtl"] body.jm-site,
[dir="rtl"] body.jm-dash,
[dir="rtl"] body.jm-site :not(.jm-mono):not(.jm-track),
[dir="rtl"] body.jm-dash :not(.jm-mono):not(.jm-track) {
    letter-spacing: 0;
    text-transform: none;
}
[dir="rtl"] body.jm-site { line-height: 1.8; }
[dir="rtl"] body.jm-dash { line-height: 1.7; }
/* Latin runs inside Arabic sentences: <bdi> keeps their direction isolated. */
body.jm-site bdi, body.jm-dash bdi { unicode-bidi: isolate; }
/* :where() keeps these at class-level specificity so component classes (.jm-btn-p, .jm-nav > a, …) win. */
:where(body.jm-site) a { color: var(--cyan); text-decoration: none; }
:where(body.jm-site) a:hover { color: var(--accent-ink); }
/* Tailwind preflight resets heading weight; the design expects bold headings everywhere. */
:where(body.jm-site) :is(h1, h2, h3, h4) { font-weight: 700; }
body.jm-site .jm-logo img { height: 44px; width: auto; }
body.jm-site :focus-visible { outline: 2px solid var(--accent2); outline-offset: 3px; border-radius: 4px; }
body.jm-site h1, body.jm-site h2, body.jm-site h3 { text-wrap: balance; }
.jm-mono { font-family: var(--mono); direction: ltr; }
.jm-skip {
    position: absolute; top: -48px; inset-inline-start: 12px; z-index: 200;
    background: var(--accent); color: var(--btn-text); font-weight: 700;
    padding: 9px 18px; border-radius: 0 0 10px 10px; transition: top .2s;
}
.jm-skip:focus { top: 0; }
.jm-wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: 22px; }
.jm-wrap--narrow { max-width: 780px; }
.jm-wrap--wide { max-width: 1280px; }
[dir="rtl"] .jm-flip-rtl { transform: scaleX(-1); }

/* ---------- header ---------- */
.jm-hdr {
    position: sticky; top: 0; z-index: 100;
    background: var(--hdr-bg);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--hdr-border);
    transition: box-shadow .2s;
}
.jm-hdr.is-scrolled { box-shadow: 0 10px 30px -18px rgba(0, 0, 0, .45); }
.jm-hdr-in { display: flex; align-items: center; gap: 18px; min-height: 70px; }
.jm-logo { display: flex; align-items: center; gap: 10px; flex: none; }
.jm-logo img { height: 44px; width: auto; }
/* Public navbar only (.jm-nav*, burger, drawer, dropdowns, avatar button): static/css/navbar.css */
.jm-tools { display: flex; align-items: center; gap: 8px; flex: none; margin-inline-start: auto; }
.jm-icon-btn, .jm-theme-toggle {
    display: grid; place-items: center; width: 40px; height: 40px; border-radius: 11px;
    border: 1px solid var(--border); background: var(--card); color: var(--muted); cursor: pointer; transition: .2s; position: relative;
    text-decoration: none;
}
.jm-icon-btn:hover, .jm-theme-toggle:hover { color: var(--accent-ink); border-color: var(--border2); transform: translateY(-2px); }
.jm-icon-btn svg, .jm-theme-toggle svg { width: 18px; height: 18px; }
.jm-lang { display: inline-flex; align-items: center; gap: 2px; border: 1px solid var(--border); border-radius: 999px; padding: 3px; background: var(--card); }
.jm-lang a { font-size: .78rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; color: var(--muted); line-height: 1.4; }
.jm-lang a[aria-current] { background: var(--grad); color: var(--btn-text); }
html.dark .jm-theme-toggle__sun { display: none; }
html:not(.dark) .jm-theme-toggle__moon { display: none; }

/* ---------- buttons & chips ---------- */
.jm-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 9px; font-weight: 700; font-size: .98rem; line-height: 1;
    padding: 15px 26px; border-radius: 13px; border: 1px solid transparent; cursor: pointer; font-family: inherit;
    transition: transform .18s, box-shadow .18s, background .18s, border-color .18s, color .18s; text-decoration: none; white-space: nowrap;
}
.jm-btn-p { background: var(--grad); color: var(--btn-text); box-shadow: var(--glow); }
.jm-btn-p:hover { transform: translateY(-2px); box-shadow: 0 16px 40px -10px rgba(249, 161, 27, .65); color: var(--btn-text); }
.jm-btn-g { background: var(--card); border-color: var(--border); color: var(--text); }
.jm-btn-g:hover { border-color: var(--faint); background: var(--card2); color: var(--text); transform: translateY(-2px); }
.jm-btn-o { background: transparent; border-color: var(--border2); color: var(--accent-ink); }
.jm-btn-o:hover { background: rgba(249, 161, 27, .1); color: var(--accent-ink); transform: translateY(-2px); }
.jm-btn-danger { background: var(--danger-soft); border-color: var(--danger-border); color: var(--danger); }
.jm-btn-s { padding: 11px 18px; font-size: .9rem; border-radius: 11px; }
.jm-btn-xs { padding: 8px 13px; font-size: .82rem; border-radius: 9px; }
.jm-btn-block { width: 100%; }
.jm-btn:disabled, .jm-btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; transform: none !important; box-shadow: none; }
.jm-btn svg { flex: none; width: 16px; height: 16px; }
.jm-chip {
    display: inline-flex; align-items: center; gap: 8px; font-size: .82rem; font-weight: 700; color: var(--accent-ink);
    background: rgba(249, 161, 27, .1); border: 1px solid rgba(249, 161, 27, .3); padding: 6px 15px; border-radius: 999px; line-height: 1.4;
    text-decoration: none; cursor: default; font-family: inherit;
}
a.jm-chip, button.jm-chip { cursor: pointer; transition: background .18s, border-color .18s; }
a.jm-chip:hover, button.jm-chip:hover { background: rgba(249, 161, 27, .18); color: var(--accent-ink); }
.jm-chip[aria-current], .jm-chip.is-active { background: var(--grad); color: var(--btn-text); border-color: transparent; }
.jm-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent2); box-shadow: 0 0 0 4px rgba(251, 191, 36, .18); }
.jm-chip--muted { color: var(--muted); background: var(--card); border-color: var(--border); }
.jm-chip--cyan { color: var(--cyan); background: var(--cyan-soft); border-color: var(--cyan-border); }
.jm-chip--success { color: var(--success); background: var(--success-soft); border-color: var(--success-border); }
.jm-chip--danger { color: var(--danger); background: var(--danger-soft); border-color: var(--danger-border); }
.jm-chip svg { width: 14px; height: 14px; }
.jm-badge-free { display: inline-flex; align-items: center; font-size: .72rem; font-weight: 700; color: var(--success); background: var(--success-soft); border: 1px solid var(--success-border); padding: 2px 9px; border-radius: 999px; }

/* ---------- hero ---------- */
.jm-hero { position: relative; padding: 88px 0 66px; text-align: center; overflow: hidden; }
.jm-hero--compact { padding: 54px 0 46px; }
.jm-hero-bg {
    position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(52rem 30rem at 85% -12%, var(--hero-glow1), transparent 60%),
                radial-gradient(46rem 28rem at 8% -6%, var(--hero-glow2), transparent 60%);
}
.jm-hero-bg::before {
    content: ""; position: absolute; inset: 0;
    background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px); background-size: 32px 32px;
    -webkit-mask-image: radial-gradient(58rem 34rem at 50% 0, #000 30%, transparent 75%);
    mask-image: radial-gradient(58rem 34rem at 50% 0, #000 30%, transparent 75%);
}
/* z-index so the header text always sits above the ambient reviews background
   (.jm-rtick-bg, z-index 0) rather than behind it. */
.jm-hero > .jm-wrap { position: relative; z-index: 1; }
.jm-welcome > .jm-wrap { position: relative; z-index: 1; }
.jm-hero h1 { font-size: clamp(2rem, 5.4vw, 3.55rem); font-weight: 700; line-height: 1.28; letter-spacing: -.5px; margin: 26px auto 18px; max-width: 22ch; }
.jm-gtext { background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; white-space: nowrap; }
.jm-lead { color: var(--muted); font-size: clamp(1.02rem, 1.9vw, 1.18rem); max-width: 44rem; margin: 0 auto 34px; }
.jm-lead b { color: var(--text); font-weight: 600; }
.jm-cta-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.jm-cta-row--start { justify-content: flex-start; }
.jm-code-float {
    position: absolute; font-family: var(--mono); direction: ltr; font-size: .78rem; color: var(--faint);
    background: var(--code-bg); border: 1px solid var(--code-border); border-radius: 10px; padding: 7px 13px; opacity: .85; pointer-events: none;
}
.jm-code-float b { color: var(--accent-ink); font-weight: 600; }
.jm-code-float i { color: var(--cyan); font-style: normal; }
@media (max-width: 1050px) { .jm-code-float { display: none; } }
/* ---------- student-reviews banner (fragments/rating-ticker.html) ---------- */
/* Five admin-selectable presentations. Shared bones first, then one block per variant.
   CARD / STRIP / DECK / SPOTLIGHT share the slide DOM and the rotation script and differ only here;
   MARQUEE has its own DOM and animates purely in CSS. */

/* --- shared: in flow by default, so it never covers the hero text on narrow screens --- */
.jm-rtick {
    position: relative; display: block; width: calc(100% - 40px); max-width: 360px;
    margin: 34px auto 0; padding: 16px 18px; text-align: start;
    background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r);
    box-shadow: var(--shadow); overflow: hidden;
}
.jm-rtick__viewport { position: relative; min-height: 132px; overflow: hidden; }

.jm-rtick__card {
    position: absolute; inset: 0; display: flex; flex-direction: column; gap: 9px;
    opacity: 0; visibility: hidden;
    transform: translateY(-64%) scale(.96);
    filter: blur(5px);
    transition: transform .62s cubic-bezier(.16, 1, .3, 1),
                opacity .42s cubic-bezier(.16, 1, .3, 1),
                filter .42s ease,
                visibility .62s;
    will-change: transform, opacity;
}
.jm-rtick__card.is-active { opacity: 1; visibility: visible; transform: translateY(0) scale(1); filter: blur(0); }
.jm-rtick__card.is-leaving { opacity: 0; visibility: visible; transform: translateY(64%) scale(.96); filter: blur(5px); }

/* Inner content lands in a short stagger behind the card — the detail that reads as "polished". */
@keyframes jm-rtick-rise {
    from { opacity: 0; transform: translateY(9px); }
    to   { opacity: 1; transform: none; }
}
.jm-rtick__card.is-active .jm-rtick__head  { animation: jm-rtick-rise .5s cubic-bezier(.16, 1, .3, 1) .05s both; }
.jm-rtick__card.is-active .jm-rtick__stars { animation: jm-rtick-rise .5s cubic-bezier(.16, 1, .3, 1) .11s both; }
.jm-rtick__card.is-active .jm-rtick__text  { animation: jm-rtick-rise .5s cubic-bezier(.16, 1, .3, 1) .17s both; }

.jm-rtick__head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.jm-rtick__who { min-width: 0; display: flex; flex-direction: column; }
.jm-rtick__name { font-size: .92rem; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jm-rtick__role { font-size: .78rem; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jm-rtick__stars { display: flex; gap: 2px; }
.jm-rtick__stars svg { width: 14px; height: 14px; color: var(--border); flex: none; }
.jm-rtick__stars svg.is-on { color: var(--accent2); }
.jm-rtick__text {
    margin: 0; color: var(--muted); font-size: .89rem; line-height: 1.65;
    display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* Progress hairline; the script restarts it on each advance and pauses it on hover/focus. */
.jm-rtick__bar { position: absolute; inset-inline: 0; bottom: 0; height: 2px; background: var(--card2); }
.jm-rtick__bar i { display: block; height: 100%; width: 0; background: var(--grad); }
.jm-rtick.is-running .jm-rtick__bar i { animation: jm-rtick-fill linear forwards; animation-duration: var(--rtick-duration, 3s); }
.jm-rtick.is-paused .jm-rtick__bar i { animation-play-state: paused; }
@keyframes jm-rtick-fill { from { width: 0; } to { width: 100%; } }

/* =============== 1. CARD — floating panel beside the hero (default) =============== */
/* From 1280px it leaves the flow and sits in the margin next to the centred hero column. .jm-hero /
   .jm-welcome are the positioned ancestors, so the offset is measured from the viewport edge where
   that free space actually is. */
@media (min-width: 1280px) {
    .jm-rtick--card {
        position: absolute; inset-inline-end: 26px; top: 50%; transform: translateY(-50%);
        width: 282px; max-width: none; margin: 0; z-index: 2;
    }
}

/* =============== 2. STRIP — slim one-line bar, slides in sideways =============== */
.jm-rtick--strip {
    max-width: 620px; padding: 10px 16px; border-radius: 999px;
}
.jm-rtick--strip .jm-rtick__viewport { min-height: 40px; }
.jm-rtick--strip .jm-rtick__card {
    flex-direction: row; align-items: center; gap: 12px;
    /* Horizontal travel. transform has no logical equivalent, so RTL is flipped below. */
    transform: translateX(28px) scale(1); filter: none;
    transition: transform .5s cubic-bezier(.16, 1, .3, 1), opacity .34s ease, visibility .5s;
}
[dir="rtl"] .jm-rtick--strip .jm-rtick__card { transform: translateX(-28px); }
.jm-rtick--strip .jm-rtick__card.is-active { transform: translateX(0); }
.jm-rtick--strip .jm-rtick__card.is-leaving { transform: translateX(-28px); filter: none; }
[dir="rtl"] .jm-rtick--strip .jm-rtick__card.is-leaving { transform: translateX(28px); }
.jm-rtick--strip .jm-rtick__who { flex-direction: row; align-items: baseline; gap: 7px; }
.jm-rtick--strip .jm-rtick__role { display: none; }
.jm-rtick--strip .jm-rtick__stars { flex: none; }
.jm-rtick--strip .jm-rtick__text {
    -webkit-line-clamp: 1; line-clamp: 1; font-size: .86rem; white-space: nowrap;
    text-overflow: ellipsis; min-width: 0; flex: 1;
}
.jm-rtick--strip .jm-rtick__card.is-active .jm-rtick__head,
.jm-rtick--strip .jm-rtick__card.is-active .jm-rtick__stars,
.jm-rtick--strip .jm-rtick__card.is-active .jm-rtick__text { animation: none; }
.jm-rtick--strip .jm-rtick__bar { display: none; }
@media (min-width: 1280px) {
    .jm-rtick--strip { max-width: 620px; margin-top: 30px; }
}

/* =============== 3. DECK — a stack with the next cards' edges showing =============== */
/* The pseudo-elements are the cards "underneath": cheaper and steadier than rendering real extra
   slides, and they never go out of sync with the rotation. */
.jm-rtick--deck { margin-top: 46px; }
.jm-rtick--deck::before,
.jm-rtick--deck::after {
    content: ""; position: absolute; inset-inline: 14px; top: -7px; height: 100%;
    background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r);
    z-index: -1;
}
.jm-rtick--deck::after { inset-inline: 26px; top: -14px; opacity: .6; }
.jm-rtick--deck .jm-rtick__card {
    transform: translateY(-16px) scale(.94) rotate(-1.4deg); transform-origin: 50% 100%;
    transition: transform .6s cubic-bezier(.16, 1, .3, 1), opacity .4s ease, visibility .6s;
}
.jm-rtick--deck .jm-rtick__card.is-active { transform: translateY(0) scale(1) rotate(0); }
/* Leaves by lifting off the top of the pile rather than sliding through it. */
.jm-rtick--deck .jm-rtick__card.is-leaving { transform: translateY(-26px) scale(1.03) rotate(2deg); filter: blur(3px); }
@media (min-width: 1280px) {
    .jm-rtick--deck {
        position: absolute; inset-inline-end: 26px; top: 50%; transform: translateY(-50%);
        width: 282px; max-width: none; margin: 0; z-index: 2;
    }
}

/* =============== 4. SPOTLIGHT — large editorial pull-quote =============== */
.jm-rtick--spotlight {
    max-width: 680px; padding: 28px 30px 26px; text-align: center;
    background: var(--card); border-color: var(--border2);
}
.jm-rtick--spotlight .jm-rtick__viewport { min-height: 186px; }
.jm-rtick--spotlight .jm-rtick__card {
    align-items: center; gap: 12px;
    /* No travel: a quote this size reads better appearing in place than sliding. */
    transform: scale(.97); filter: blur(4px);
    transition: transform .55s cubic-bezier(.16, 1, .3, 1), opacity .45s ease, filter .45s ease, visibility .55s;
}
.jm-rtick--spotlight .jm-rtick__card.is-active { transform: scale(1); filter: blur(0); }
.jm-rtick--spotlight .jm-rtick__card.is-leaving { transform: scale(1.03); filter: blur(4px); }
.jm-rtick--spotlight .jm-rtick__quote {
    font-family: Georgia, "Times New Roman", serif; font-size: 3.2rem; line-height: .7;
    color: var(--accent2); opacity: .55; height: 26px;
}
.jm-rtick--spotlight .jm-rtick__text {
    -webkit-line-clamp: 4; line-clamp: 4; font-size: 1.06rem; line-height: 1.7; color: var(--text);
    max-width: 46ch;
}
.jm-rtick--spotlight .jm-rtick__head { order: 3; }
.jm-rtick--spotlight .jm-rtick__who { align-items: center; text-align: center; }
.jm-rtick--spotlight .jm-rtick__stars svg { width: 16px; height: 16px; }
@media (min-width: 1280px) {
    .jm-rtick--spotlight { margin-top: 40px; }
}

/* =============== 5. MARQUEE — continuous ribbon, CSS-only =============== */
.jm-rtick--ribbon {
    max-width: none; width: 100%; margin: 34px 0 0; padding: 12px 0;
    border-inline: 0; border-radius: 0; box-shadow: none; background: transparent;
    /* Fades the ends so pills enter and leave instead of being chopped off. */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.jm-rtick__track { display: flex; width: max-content; animation: jm-rtick-scroll 38s linear infinite; }
/* One copy's width is exactly half the track, so resetting there is invisible. */
@keyframes jm-rtick-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
[dir="rtl"] .jm-rtick__track { animation-name: jm-rtick-scroll-rtl; }
@keyframes jm-rtick-scroll-rtl { from { transform: translateX(0); } to { transform: translateX(50%); } }
.jm-rtick--ribbon:hover .jm-rtick__track { animation-play-state: paused; }
.jm-rtick__lane { display: flex; gap: 12px; padding-inline-end: 12px; }
.jm-rtick__pill {
    display: inline-flex; align-items: center; gap: 10px; flex: none;
    max-width: 440px; padding: 8px 16px 8px 9px; border-radius: 999px;
    background: var(--bg2); border: 1px solid var(--border); box-shadow: var(--shadow);
}
[dir="rtl"] .jm-rtick__pill { padding: 8px 9px 8px 16px; }
.jm-rtick__pillavatar { flex: none; }
.jm-rtick__pillbody { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.jm-rtick__pillstars { display: inline-flex; gap: 1px; flex: none; }
.jm-rtick__pillstars svg { width: 12px; height: 12px; color: var(--border); }
.jm-rtick__pillstars svg.is-on { color: var(--accent2); }
.jm-rtick__pilltext {
    font-size: .85rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.jm-rtick__pillname { font-size: .82rem; color: var(--text); white-space: nowrap; flex: none; }
.jm-rtick__pillname::before { content: "— "; color: var(--faint); }

/* =============== 6. RIBBON-DUAL — two lanes, opposite directions =============== */
.jm-rtick--ribbon-dual { padding: 10px 0; }
.jm-rtick--ribbon-dual .jm-rtick__track + .jm-rtick__track { margin-top: 10px; }
/* Slightly different speed as well as direction, so the two rows never march in lockstep. */
.jm-rtick__track--reverse { animation-name: jm-rtick-scroll-rtl; animation-duration: 46s; }
[dir="rtl"] .jm-rtick__track--reverse { animation-name: jm-rtick-scroll; }

/* =============== 7. COLUMN — vertical ribbon beside the hero =============== */
.jm-rtick--column {
    max-width: 340px; padding: 0; background: transparent; border: 0; box-shadow: none;
    overflow: hidden; height: 300px;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
}
.jm-rtick--column .jm-rtick__track {
    flex-direction: column; width: 100%; gap: 10px;
    animation: jm-rtick-scroll-y 34s linear infinite;
}
.jm-rtick--column .jm-rtick__lane { flex-direction: column; gap: 10px; padding: 0 0 10px; }
.jm-rtick--column .jm-rtick__pill { max-width: none; width: 100%; }
.jm-rtick--column .jm-rtick__pilltext { white-space: normal; -webkit-line-clamp: 2; line-clamp: 2;
    display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
@keyframes jm-rtick-scroll-y { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.jm-rtick--column:hover .jm-rtick__track { animation-play-state: paused; }
@media (min-width: 1280px) {
    .jm-rtick--column {
        position: absolute; inset-inline-end: 20px; top: 50%; transform: translateY(-50%);
        width: 320px; max-width: none; margin: 0; z-index: 2;
    }
}

/* =============== 8 & 9. BACKGROUND FAMILY — ambient, behind the header =============== */
/* Covers the whole header, sits under the content, and never takes a click. Hidden below 1024px:
   over a phone-width headline this is noise, not atmosphere. */
.jm-rtick-bg {
    position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
    display: none;
}
@media (min-width: 1024px) { .jm-rtick-bg { display: block; } }
/* Keeps the headline readable over the top of it. */
/* Protects the headline: opaque at the centre where the text sits, clear at the edges where the
   reviews are, so the copy stays crisp without hiding them. */
.jm-rtick-bg::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(54% 52% at 50% 46%,
        var(--bg) 0%,
        color-mix(in srgb, var(--bg) 88%, transparent) 46%,
        transparent 78%);
}
/* Readability: the pills are opaque with a real border and shadow, and the quote uses the body text
   colour rather than the muted one. The layer's own opacity does the "sits behind" work, so the text
   inside each pill does not also need to be faint — that combination was what made them hard to read. */
.jm-rtick-bg .jm-rtick__pill {
    background: var(--bg2); border-color: var(--border);
    box-shadow: 0 8px 22px -14px rgba(15, 23, 42, .35);
}
.jm-rtick-bg .jm-rtick__pilltext {
    white-space: nowrap; max-width: 34ch; overflow: hidden; text-overflow: ellipsis;
    color: var(--text); font-size: .87rem;
}
.jm-rtick-bg .jm-rtick__pillname { color: var(--muted); }
.jm-rtick-bg .jm-rtick__pillstars svg.is-on { color: var(--accent); }

/* --- 8. BACKDROP: a slow column of faded cards drifting up behind the text --- */
.jm-rtick-bg--backdrop .jm-rtick-bg__layer {
    position: absolute; inset-inline: 0; top: 0;
    display: flex; flex-direction: column;
    /* Was .3 with a blur, which made the quotes unreadable. The centre wash below is what protects the
       headline, so the cards themselves can be close to full strength. */
    opacity: .72;
    animation: jm-rtick-bg-drift 52s linear infinite;
}
.jm-rtick-bg--backdrop .jm-rtick-bg__lane {
    display: flex; flex-direction: column; gap: 16px; padding-bottom: 16px;
}
/* Alternating indents keep the column from looking like a list. */
.jm-rtick-bg--backdrop .jm-rtick-bg__item { display: flex; }
.jm-rtick-bg--backdrop .jm-rtick-bg__item[data-slot="1"] { justify-content: flex-end; }
.jm-rtick-bg--backdrop .jm-rtick-bg__item[data-slot="2"] { justify-content: center; }
.jm-rtick-bg--backdrop .jm-rtick-bg__item[data-slot="3"] { justify-content: flex-start; padding-inline-start: 8%; }
.jm-rtick-bg--backdrop .jm-rtick-bg__item[data-slot="4"] { justify-content: flex-end; padding-inline-end: 6%; }
.jm-rtick-bg--backdrop .jm-rtick-bg__item[data-slot="5"] { justify-content: center; }
@keyframes jm-rtick-bg-drift { from { transform: translateY(0); } to { transform: translateY(-50%); } }

/* --- 9. BACKDROP-RIBBONS: the double ribbon, moved into the header itself --- */
/* Same crossing motion as the standalone Double ribbon, but as header atmosphere: the lanes sit
   behind the headline and run full width, so the two rows read as a moving texture. */
.jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__layer {
    position: absolute; inset-inline: 0; top: 50%; transform: translateY(-50%);
    display: flex; flex-direction: column; gap: 16px;
    opacity: .72;
}
.jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__lane {
    display: flex; width: max-content; gap: 14px;
    animation: jm-rtick-scroll 44s linear infinite;
}
/* The second lane crosses the first. */
.jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__lane:nth-child(2) {
    animation-name: jm-rtick-scroll-rtl; animation-duration: 54s;
}
[dir="rtl"] .jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__lane { animation-name: jm-rtick-scroll-rtl; }
[dir="rtl"] .jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__lane:nth-child(2) { animation-name: jm-rtick-scroll; }
/* Each lane holds one copy of the reviews, so it is doubled inside to loop seamlessly. */
.jm-rtick-bg--backdrop-ribbons .jm-rtick-bg__item { flex: none; }
.jm-rtick-bg--backdrop-ribbons:hover .jm-rtick-bg__lane { animation-play-state: paused; }

/* --- 9. BUBBLES: chips parked around the header, each breathing on its own offset --- */
.jm-rtick-bg--bubbles .jm-rtick-bg__layer { position: absolute; inset: 0; opacity: .74; }
/* Only the first pass is placed; the duplicate exists for the other variants and is dropped here. */
.jm-rtick-bg--bubbles .jm-rtick-bg__lane:nth-child(2) { display: none; }
.jm-rtick-bg--bubbles .jm-rtick-bg__lane { display: block; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item { position: absolute; animation: jm-rtick-float 9s ease-in-out infinite; }
/* Six parking spots, well clear of the centred headline. */
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="0"] { top: 12%;  inset-inline-start: 3%;  animation-delay: 0s; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="1"] { top: 26%;  inset-inline-end: 2%;    animation-delay: 1.4s; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="2"] { bottom: 16%; inset-inline-start: 6%; animation-delay: 2.6s; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="3"] { bottom: 9%; inset-inline-end: 7%;   animation-delay: 3.8s; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="4"] { top: 48%;  inset-inline-start: 1%;  animation-delay: 5s; }
.jm-rtick-bg--bubbles .jm-rtick-bg__item[data-slot="5"] { top: 62%;  inset-inline-end: 3%;    animation-delay: 6.2s; }
@keyframes jm-rtick-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-11px); }
}

/* --- motion opt-outs, all variants --- */
/* Both end up as an instant change: the review still advances, it just doesn't travel.
   On the admin "animations.enabled" switch: custom.css applies `transition-duration: 0s !important`
   to every element when it is off, so nothing here can give the banner its own timing — that global
   rule always wins. What these rules do is neutralise the travel and the blur (transform/filter are
   not in the kill-switch), so a card appears in place instead of snapping in from 64% above. To see
   the banner animated, turn animations back on in Settings → Templates. */
html.no-animations .jm-rtick__card { transform: none; filter: none; }
html.no-animations .jm-rtick__card.is-leaving { transform: none; filter: none; opacity: 0; }
html.no-animations .jm-rtick__card.is-active .jm-rtick__head,
html.no-animations .jm-rtick__card.is-active .jm-rtick__stars,
html.no-animations .jm-rtick__card.is-active .jm-rtick__text { animation: none; }
html.no-animations .jm-rtick__bar { display: none; }
html.no-animations .jm-rtick__bar i { animation: none; }
/* A marquee with no motion is just a clipped row, so show a static wrapped set instead. */
html.no-animations .jm-rtick__track { animation: none; width: 100%; flex-wrap: wrap; gap: 10px; }
html.no-animations .jm-rtick--ribbon .jm-rtick__lane[aria-hidden="true"] { display: none; }
html.no-animations .jm-rtick--column { height: auto; }
html.no-animations .jm-rtick-bg__layer { animation: none; }
html.no-animations .jm-rtick-bg--bubbles .jm-rtick-bg__item { animation: none; }
html.no-animations .jm-rtick-bg__lane { animation: none; flex-wrap: wrap; width: 100%; }

@media (prefers-reduced-motion: reduce) {
    .jm-rtick__card { transition: none; transform: none; filter: none; }
    .jm-rtick__card.is-leaving { transform: none; filter: none; opacity: 0; visibility: hidden; }
    .jm-rtick__card.is-active .jm-rtick__head,
    .jm-rtick__card.is-active .jm-rtick__stars,
    .jm-rtick__card.is-active .jm-rtick__text { animation: none; }
    .jm-rtick__bar { display: none; }
    .jm-rtick__bar i { animation: none; }
    .jm-rtick__track { animation: none; width: 100%; flex-wrap: wrap; gap: 10px; }
    .jm-rtick--ribbon .jm-rtick__lane[aria-hidden="true"] { display: none; }
    .jm-rtick--column { height: auto; }
    .jm-rtick-bg__layer { animation: none; }
    .jm-rtick-bg--bubbles .jm-rtick-bg__item { animation: none; }
    .jm-rtick-bg__lane { animation: none; flex-wrap: wrap; width: 100%; }
}

/* Stats bar. auto-fit so a two-stat configuration centres instead of leaving two empty cells —
   HomeController drops slots with no value, so the count is admin-driven. */
.jm-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; margin-top: 64px; }
.jm-stat { background: var(--stat-bg); padding: 22px 14px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 7px; }
.jm-stat b { display: block; font-size: 1.5rem; font-weight: 700; background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; font-variant-numeric: tabular-nums; }
.jm-stat span { color: var(--muted); font-size: .88rem; }
/* Admin-chosen icon (fragments/stat-icons.html), in an accent-tinted disc above the figure. */
.jm-stat__icon {
    display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%;
    background: rgba(249, 161, 27, .12); color: var(--accent-ink); flex: none;
}
.jm-stat__icon svg { width: 19px; height: 19px; }
@media (max-width: 520px) {
    .jm-stats { margin-top: 40px; }
    .jm-stat { padding: 16px 10px; gap: 5px; }
    .jm-stat__icon { width: 32px; height: 32px; }
    .jm-stat__icon svg { width: 16px; height: 16px; }
}
@media (max-width: 640px) { .jm-stats { grid-template-columns: 1fr 1fr; } }

/* ---------- sections ---------- */
.jm-sec { padding: 78px 0; position: relative; }
.jm-sec--tight { padding: 44px 0; }
.jm-sec-alt { background: linear-gradient(180deg, transparent, var(--card) 18%, var(--card) 82%, transparent); }
.jm-sec-head { max-width: 660px; margin: 0 auto 48px; text-align: center; }
.jm-sec-head--start { margin-inline: 0; text-align: start; }
.jm-sec-head h1, .jm-sec-head h2 { font-size: clamp(1.55rem, 3.4vw, 2.2rem); font-weight: 700; line-height: 1.35; margin: 16px 0 12px; letter-spacing: -.3px; }
.jm-sec-head p { color: var(--muted); margin: 0; font-size: 1.02rem; }
.jm-sec-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; margin-bottom: 34px; }
.jm-sec-row .jm-sec-head { margin: 0; }

/* ---------- course cards ---------- */
.jm-cgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.jm-cgrid--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 980px) { .jm-cgrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .jm-cgrid { grid-template-columns: 1fr; } }
.jm-ccard {
    display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden;
    transition: transform .22s, border-color .22s, box-shadow .22s; position: relative;
}
.jm-ccard:hover { transform: translateY(-5px); border-color: var(--border2); box-shadow: var(--shadow); }
.jm-cthumb { position: relative; aspect-ratio: 16/9; overflow: hidden; background: var(--thumb-bg); display: block; }
.jm-cthumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s; display: block; }
.jm-ccard:hover .jm-cthumb img { transform: scale(1.045); }
.jm-cthumb-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--faint); background: linear-gradient(135deg, var(--card2), var(--thumb-bg)); }
.jm-cthumb-ph svg { width: 42px; height: 42px; }
.jm-cbadge {
    position: absolute; top: 12px; inset-inline-start: 12px; z-index: 2; font-size: .75rem; font-weight: 700; color: var(--btn-text);
    background: var(--grad); padding: 5px 12px; border-radius: 999px; box-shadow: 0 6px 18px -6px rgba(249, 161, 27, .6);
}
.jm-cbadge--end { inset-inline-start: auto; inset-inline-end: 12px; }
.jm-cbadge--success { background: #22c55e; color: #052e16; }
.jm-cbody { display: flex; flex-direction: column; gap: 10px; padding: 20px 20px 22px; flex: 1; }
.jm-cbody h3, .jm-cbody h2 { margin: 0; font-size: 1.04rem; font-weight: 700; line-height: 1.5; }
.jm-cbody h3 a, .jm-cbody h2 a { color: var(--text); }
.jm-cbody h3 a:hover, .jm-cbody h2 a:hover { color: var(--accent-ink); }
.jm-ccard--stretch .jm-cbody h3 a::after { content: ""; position: absolute; inset: 0; }
.jm-clevel { display: inline-flex; align-items: center; gap: 6px; color: var(--faint); font-size: .82rem; font-weight: 600; flex-wrap: wrap; }
.jm-clevel svg { color: var(--accent); width: 14px; height: 14px; }
.jm-cbody p { margin: 0; color: var(--muted); font-size: .9rem; line-height: 1.75; flex: 1; }
.jm-cmore { display: inline-flex; align-items: center; gap: 7px; color: var(--accent-ink); font-weight: 700; font-size: .9rem; margin-top: 4px; }
.jm-cmore svg { width: 16px; height: 16px; transition: transform .2s; }
.jm-ccard:hover .jm-cmore svg { transform: translateX(-4px); }
[dir="ltr"] .jm-ccard:hover .jm-cmore svg { transform: translateX(4px); }
.jm-cmeta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; color: var(--faint); font-size: .82rem; }
.jm-cmeta span { display: inline-flex; align-items: center; gap: 5px; }
.jm-cmeta svg { width: 14px; height: 14px; }
.jm-rating { display: inline-flex; align-items: center; gap: 4px; color: var(--accent2); font-size: .82rem; font-weight: 700; }
.jm-rating svg { width: 14px; height: 14px; }
.jm-rating small { color: var(--faint); font-weight: 600; }
.jm-cprice { display: flex; align-items: center; gap: 10px; margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.jm-price { font-size: 1.05rem; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.jm-price--lg { font-size: 1.9rem; }
.jm-price-old { color: var(--faint); font-size: .85rem; text-decoration: line-through; }
.jm-cprice .jm-badge-free, .jm-cprice .jm-chip { margin-inline-start: auto; }
.jm-cactions { display: flex; gap: 8px; margin-top: 8px; position: relative; z-index: 3; }
.jm-cactions .jm-btn { flex: 1; }
.jm-progress { height: 8px; border-radius: 999px; background: var(--card2); overflow: hidden; }
.jm-progress > span { display: block; height: 100%; border-radius: 999px; background: var(--grad); }

/* ---------- feature cards ---------- */
.jm-fgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.jm-fgrid--3 { grid-template-columns: repeat(3, 1fr); }
.jm-fgrid--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 980px) { .jm-fgrid, .jm-fgrid--3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .jm-fgrid, .jm-fgrid--3, .jm-fgrid--2 { grid-template-columns: 1fr; } }
.jm-fcard { background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 26px 22px; transition: transform .2s, border-color .2s; }
.jm-fcard:hover { transform: translateY(-4px); border-color: var(--faint); }
.jm-ficon { width: 52px; height: 52px; border-radius: 14px; display: grid; place-items: center; background: rgba(249, 161, 27, .12); border: 1px solid rgba(249, 161, 27, .28); color: var(--accent-ink); margin-bottom: 16px; }
.jm-ficon svg { width: 24px; height: 24px; }
.jm-fcard h3 { margin: 0 0 8px; font-size: 1.05rem; font-weight: 700; }
.jm-fcard p { margin: 0; color: var(--muted); font-size: .92rem; }

/* ---------- testimonials ---------- */
.jm-tcols { columns: 3 300px; column-gap: 18px; }
.jm-tcard {
    break-inside: avoid; margin-bottom: 18px; background: var(--bg2); border-radius: 14px; padding: 20px;
    box-shadow: 0 14px 34px -16px rgba(0, 0, 0, .5); border: 1px solid var(--border);
}
.jm-tcard img { border-radius: 9px; width: 100%; }
.jm-tcard-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.jm-tcard-head img, .jm-tcard-head .jm-avatar { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; display: grid; place-items: center; background: var(--grad); color: var(--btn-text); font-weight: 700; }
.jm-tcard-head b { display: block; font-size: .95rem; color: var(--text); }
.jm-tcard-head small { color: var(--faint); font-size: .8rem; }
.jm-tcard .jm-stars { color: var(--accent2); letter-spacing: 2px; font-size: .9rem; margin-bottom: 8px; }
.jm-tcard p { margin: 0; color: var(--muted); font-size: .93rem; line-height: 1.75; }
.jm-tnote { text-align: center; color: var(--faint); font-size: .88rem; margin-top: 26px; }

/* ---------- story / split ---------- */
.jm-split { display: grid; grid-template-columns: 1fr 1.15fr; gap: 56px; align-items: center; }
@media (max-width: 880px) { .jm-split { grid-template-columns: 1fr; gap: 36px; } }
.jm-portrait { position: relative; max-width: 400px; margin-inline: auto; }
.jm-portrait::before { content: ""; position: absolute; inset: 8% 4% 0; border-radius: 26px; background: linear-gradient(160deg, rgba(249, 161, 27, .32), rgba(56, 189, 248, .14) 70%); filter: blur(2px); }
.jm-portrait::after { content: ""; position: absolute; inset: auto 8% 0; height: 38%; background: linear-gradient(180deg, transparent, var(--bg) 92%); }
.jm-portrait img { position: relative; z-index: 1; filter: drop-shadow(0 24px 40px rgba(0, 0, 0, .5)); }
.jm-story h2 { font-size: clamp(1.5rem, 3vw, 2.05rem); margin: 14px 0 14px; line-height: 1.4; }
.jm-story p { color: var(--muted); margin: 0 0 22px; }
.jm-tl { list-style: none; margin: 34px 0 0; padding: 0; position: relative; }
.jm-tl::before { content: ""; position: absolute; inset-block: 6px; inset-inline-start: 7px; width: 2px; background: linear-gradient(180deg, var(--accent), var(--border)); }
.jm-tl li { position: relative; padding-inline-start: 38px; padding-bottom: 24px; }
.jm-tl li:last-child { padding-bottom: 0; }
.jm-tl li::before { content: ""; position: absolute; inset-inline-start: 0; top: 7px; width: 16px; height: 16px; border-radius: 50%; background: var(--bg); border: 3px solid var(--accent); box-shadow: 0 0 0 4px rgba(249, 161, 27, .15); }
.jm-tl b { display: block; font-size: 1rem; color: var(--text); }
.jm-tl .jm-yr { font-family: var(--mono); color: var(--accent-ink); font-weight: 700; font-size: .85rem; margin-inline-end: 10px; }
.jm-tl p { margin: 3px 0 0; color: var(--muted); font-size: .92rem; }

/* ---------- blog cards ---------- */
.jm-bgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
@media (max-width: 920px) { .jm-bgrid { grid-template-columns: 1fr; } }
.jm-bcard {
    position: relative; display: flex; flex-direction: column; gap: 12px; background: var(--card); border: 1px solid var(--border);
    border-radius: var(--r); padding: 26px 24px; transition: transform .2s, border-color .2s, box-shadow .2s;
}
.jm-bcard:hover { transform: translateY(-5px); border-color: var(--border2); box-shadow: var(--shadow); }
.jm-bcard--img { padding: 0; overflow: hidden; }
.jm-bcard--img .jm-bbody { padding: 22px 24px 24px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.jm-btags { display: flex; gap: 8px; flex-wrap: wrap; }
.jm-btag { font-size: .74rem; font-weight: 700; color: var(--cyan); background: var(--cyan-soft); border: 1px solid var(--cyan-border); padding: 3px 11px; border-radius: 999px; }
.jm-bcard h3, .jm-bcard h2 { margin: 0; font-size: 1.06rem; line-height: 1.55; font-weight: 700; }
.jm-bcard h3 a, .jm-bcard h2 a { color: var(--text); }
.jm-bcard h3 a::after, .jm-bcard h2 a::after { content: ""; position: absolute; inset: 0; }
.jm-bcard h3 a:hover, .jm-bcard h2 a:hover { color: var(--accent-ink); }
.jm-bcard p { margin: 0; color: var(--muted); font-size: .9rem; flex: 1; }
.jm-bmeta { display: flex; align-items: center; gap: 14px; color: var(--faint); font-size: .82rem; flex-wrap: wrap; }

/* ---------- FAQ / accordion ---------- */
.jm-faq { max-width: 780px; margin-inline: auto; }
.jm-faq--full { max-width: none; }
.jm-faq details { border: 1px solid var(--border); border-radius: 14px; background: var(--card); margin-bottom: 12px; overflow: hidden; transition: border-color .2s; }
.jm-faq details[open] { border-color: var(--border2); }
.jm-faq summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 14px; padding: 19px 22px; font-weight: 700; font-size: 1.01rem; }
.jm-faq summary::-webkit-details-marker { display: none; }
.jm-faq summary::after { content: "+"; margin-inline-start: auto; font-size: 1.5rem; font-weight: 400; color: var(--accent-ink); line-height: 1; transition: transform .25s; flex: none; }
.jm-faq details[open] summary::after { transform: rotate(45deg); }
.jm-faq .jm-ans { padding: 0 22px 20px; color: var(--muted); font-size: .96rem; }
.jm-faq .jm-ans p { margin: 0; }
/* Plain-text answers (course FAQ) keep the line breaks the admin typed. */
.jm-faq .jm-ans-text { white-space: pre-line; overflow-wrap: anywhere; }

/* ---------- CTA band ---------- */
.jm-band {
    position: relative; border: 1px solid var(--border2); border-radius: 22px; padding: 54px 30px; text-align: center; overflow: hidden;
    background: radial-gradient(40rem 20rem at 50% 120%, rgba(249, 161, 27, .17), transparent 65%), var(--bg2);
}
.jm-band h2 { font-size: clamp(1.5rem, 3.4vw, 2.1rem); margin: 0 0 12px; }
.jm-band p { color: var(--muted); max-width: 38rem; margin: 0 auto 30px; }

/* ---------- breadcrumbs ---------- */
.jm-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; list-style: none; padding: 0; margin: 0 0 8px; color: var(--faint); font-size: .86rem; }
.jm-crumbs a { color: var(--muted); }
.jm-crumbs a:hover { color: var(--accent-ink); }
.jm-crumbs li:not(:last-child)::after { content: "‹"; margin-inline-start: 9px; opacity: .6; }
[dir="ltr"] .jm-crumbs li:not(:last-child)::after { content: "›"; }
.jm-crumbs [aria-current] { color: var(--text); font-weight: 600; }

/* ---------- course detail ---------- */
.jm-chero { padding: 54px 0 70px; position: relative; }
.jm-chero .jm-split { grid-template-columns: 1.2fr 1fr; gap: 48px; align-items: center; }
@media (max-width: 880px) { .jm-chero .jm-split { grid-template-columns: 1fr; } }
.jm-chero h1 { font-size: clamp(1.65rem, 3.8vw, 2.5rem); line-height: 1.35; margin: 18px 0 16px; letter-spacing: -.3px; }
.jm-chero .jm-lead { margin: 0 0 26px; text-align: start; font-size: 1.05rem; }
.jm-meta-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 30px; }
.jm-meta-chip { display: inline-flex; align-items: center; gap: 8px; font-size: .85rem; font-weight: 600; color: var(--muted); background: var(--card); border: 1px solid var(--border); padding: 8px 15px; border-radius: 999px; text-decoration: none; }
.jm-meta-chip svg { color: var(--accent-ink); width: 16px; height: 16px; }
.jm-cimg { position: relative; border-radius: var(--r); overflow: hidden; border: 1px solid var(--border); box-shadow: var(--shadow); background: var(--thumb-bg); }
.jm-cimg img { width: 100%; display: block; }
.jm-cimg::after { content: ""; position: absolute; inset: 0; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06); border-radius: var(--r); pointer-events: none; }
.jm-play { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(7, 11, 23, .35); cursor: pointer; border: 0; color: #fff; transition: background .2s; }
.jm-play:hover { background: rgba(7, 11, 23, .5); }
.jm-play span { width: 70px; height: 70px; border-radius: 50%; background: var(--grad); color: var(--btn-text); display: grid; place-items: center; box-shadow: var(--glow); }
.jm-play svg { width: 28px; height: 28px; }
.jm-learn { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; max-width: 920px; margin-inline: auto; list-style: none; padding: 0; }
@media (max-width: 720px) { .jm-learn { grid-template-columns: 1fr; } }
.jm-learn li { display: flex; gap: 13px; align-items: flex-start; background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 17px 18px; font-size: .95rem; color: var(--learn); }
.jm-learn svg { flex: none; color: var(--accent-ink); margin-top: 3px; width: 18px; height: 18px; }
/* Course page: every goal in ONE card, a tick before each, the ones past the 8th folded behind "Show more" */
.jm-learn-box { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 20px 22px; }
.jm-learn--box { gap: 10px 28px; margin: 0; }
.jm-learn--box li { background: none; border: 0; border-radius: 0; padding: 0; gap: 10px; font-size: .92rem; line-height: 1.55; }
.jm-learn--box svg { width: 16px; height: 16px; margin-top: 4px; }
.jm-learn-box:not(.is-expanded) .jm-learn__extra { display: none; }
.jm-link-btn.jm-learn-box__more { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; padding: 4px 0; }
.jm-learn-box__more svg { width: 16px; height: 16px; transition: transform .2s; }
.jm-learn-box__more[aria-expanded="true"] svg { transform: rotate(180deg); }
.jm-learn-box__more:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) { .jm-learn-box__more svg { transition: none; } }
.jm-two { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; max-width: 920px; margin-inline: auto; }
@media (max-width: 720px) { .jm-two { grid-template-columns: 1fr; } }
.jm-pane { background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 28px 26px; }
.jm-pane--solid { background: var(--bg2); }
.jm-pane--tight { padding: 20px; }
.jm-pane h2, .jm-pane h3 { margin: 0 0 12px; font-size: 1.12rem; display: flex; align-items: center; gap: 10px; }
.jm-pane h2 svg, .jm-pane h3 svg { color: var(--accent-ink); width: 20px; height: 20px; }
.jm-pane p { margin: 0; color: var(--muted); font-size: .95rem; }
.jm-pane ul { margin: 0; padding-inline-start: 1.2em; color: var(--muted); font-size: .95rem; }
.jm-pane li::marker { color: var(--accent2); }
.jm-inst { display: flex; gap: 26px; align-items: center; background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 30px; max-width: 920px; margin-inline: auto; flex-wrap: wrap; }
.jm-inst img, .jm-inst .jm-avatar { width: 110px; height: 110px; object-fit: cover; object-position: top; border-radius: 50%; background: linear-gradient(160deg, rgba(249, 161, 27, .35), rgba(56, 189, 248, .2)); flex: none; display: grid; place-items: center; font-size: 2rem; font-weight: 700; color: var(--text); }
.jm-inst .jm-in-b { flex: 1; min-width: 250px; }
.jm-inst h3 { margin: 0 0 4px; font-size: 1.15rem; }
.jm-inst .jm-role { color: var(--accent-ink); font-size: .88rem; font-weight: 700; margin: 0 0 10px; }
.jm-inst p { color: var(--muted); font-size: .93rem; margin: 0; }
.jm-soc { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.jm-soc a, .jm-soc button { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 11px; background: var(--card2); border: 1px solid var(--border); color: var(--muted); transition: .2s; cursor: pointer; }
.jm-soc a:hover, .jm-soc button:hover { color: var(--accent-ink); border-color: var(--border2); transform: translateY(-2px); }
.jm-soc svg { width: 18px; height: 18px; }

/* Sticky pricing pane (course detail) */
.jm-pricing { position: sticky; top: calc(90px + var(--ann-bar-h, 0px)); }
/* Flash when the band's "Enroll in this course" CTA points at this card (course-landing.js adds the
   class for ~1.6s). On desktop the card is usually already on screen, so this is the feedback that
   tells the visitor the click did something. */
.jm-pricing.is-highlight { animation: jm-pricing-flash 1.6s ease-out 1; }
@keyframes jm-pricing-flash {
    0%   { box-shadow: 0 0 0 0 rgba(249, 161, 27, .55); }
    18%  { box-shadow: 0 0 0 7px rgba(249, 161, 27, .28); }
    100% { box-shadow: 0 0 0 16px rgba(249, 161, 27, 0); }
}
/* With motion off the global kill-switch zeroes the animation, so fall back to a plain outline —
   otherwise the click would once again produce no visible feedback at all. */
html.no-animations .jm-pricing.is-highlight { animation: none; outline: 2px solid var(--accent); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
    .jm-pricing.is-highlight { animation: none; outline: 2px solid var(--accent); outline-offset: 3px; }
}
.jm-pricing .jm-price-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.jm-price-row .jm-price-note { flex-basis: 100%; margin: -10px 0 0; font-size: .875rem; font-weight: 700; color: var(--accent-ink); }
.jm-pricing .jm-includes { list-style: none; margin: 18px 0 0; padding: 18px 0 0; border-top: 1px solid var(--border); display: grid; gap: 10px; font-size: .9rem; color: var(--muted); }
.jm-pricing .jm-includes li { display: flex; align-items: center; gap: 10px; }
.jm-pricing .jm-includes svg { width: 16px; height: 16px; color: var(--accent-ink); flex: none; }
.jm-mobile-cta { position: fixed; bottom: 0; inset-inline: 0; z-index: 80; background: var(--bg2); border-top: 1px solid var(--border); padding: 12px 18px; display: none; align-items: center; gap: 14px; box-shadow: 0 -10px 30px -18px rgba(0, 0, 0, .5); }
@media (max-width: 1023px) { .jm-mobile-cta { display: flex; } body.jm-site.has-mobile-cta { padding-bottom: 80px; } }

/* ---------- article ---------- */
.jm-art-head { max-width: 760px; margin-inline: auto; padding: 50px 0 8px; }
.jm-art-head h1 { font-size: clamp(1.6rem, 3.6vw, 2.35rem); line-height: 1.4; margin: 18px 0 16px; letter-spacing: -.4px; }
.jm-art-meta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; color: var(--faint); font-size: .88rem; padding: 14px 0; border-block: 1px solid var(--border); margin-top: 22px; }
.jm-art-meta .jm-avatar, .jm-art-meta img { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; object-position: top; background: linear-gradient(160deg, rgba(249, 161, 27, .4), rgba(56, 189, 248, .25)); display: grid; place-items: center; font-weight: 700; color: var(--text); }
.jm-art-meta b { color: var(--text); display: block; font-size: .92rem; }
.jm-art-meta .jm-spacer { margin-inline-start: auto; }
.jm-art-img { max-width: 760px; margin: 30px auto 0; }
.jm-prose { max-width: 760px; margin-inline: auto; font-size: 1.04rem; line-height: 1.85; color: var(--prose); }
.jm-prose--wide { max-width: none; }
.jm-prose h1 { font-size: 1.8rem; line-height: 1.35; margin: 0 0 .8em; color: var(--text); }
.jm-prose h2 { font-size: 1.5rem; line-height: 1.4; margin: 2.4em 0 .7em; color: var(--text); letter-spacing: -.3px; }
.jm-prose h3 { font-size: 1.18rem; margin: 2em 0 .6em; color: var(--text); }
.jm-prose h4 { font-size: 1.05rem; margin: 1.6em 0 .5em; color: var(--text); }
.jm-prose p { margin: 0 0 1.25em; }
.jm-prose ul, .jm-prose ol { margin: 0 0 1.4em; padding-inline-start: 1.5em; }
.jm-prose ul { list-style: disc; } .jm-prose ol { list-style: decimal; }
.jm-prose li { margin-bottom: .55em; }
.jm-prose li::marker { color: var(--accent2); }
.jm-prose a { text-decoration: underline; text-underline-offset: 3px; color: var(--cyan); }
.jm-prose a:hover { color: var(--accent-ink); }
.jm-prose strong { color: var(--text); }
.jm-prose img { background: #fff; border-radius: 14px; padding: 14px; margin: 2em auto; border: 1px solid var(--border); box-shadow: var(--shadow); }
.jm-prose blockquote { margin: 1.6em 0; padding: 4px 22px; border-inline-start: 3px solid var(--accent); background: var(--card); border-radius: 0 12px 12px 0; color: var(--muted); }
[dir="rtl"] .jm-prose blockquote { border-radius: 12px 0 0 12px; }
.jm-prose code { font-family: var(--mono); font-size: .9em; background: var(--card2); border: 1px solid var(--border); padding: 2px 7px; border-radius: 6px; color: var(--accent-ink); direction: ltr; unicode-bidi: embed; }
.jm-prose pre { background: #0a1020; color: #e9eefa; border: 1px solid rgba(148, 163, 184, .15); border-radius: 12px; padding: 18px 20px; overflow-x: auto; direction: ltr; text-align: left; margin: 0 0 1.5em; font-family: var(--mono); font-size: .88rem; line-height: 1.7; }
.jm-prose pre code { background: none; border: 0; padding: 0; color: inherit; font-size: inherit; }
.jm-prose table { width: 100%; border-collapse: collapse; margin: 0 0 1.5em; font-size: .95rem; display: block; overflow-x: auto; }
.jm-prose th, .jm-prose td { border: 1px solid var(--border); padding: 10px 14px; text-align: start; }
.jm-prose th { background: var(--card2); color: var(--text); font-weight: 700; }
.jm-prose hr { border: 0; border-top: 1px solid var(--border); margin: 2.5em 0; }
.jm-prose iframe, .jm-prose video { max-width: 100%; border-radius: 12px; }
.jm-tldr { background: rgba(249, 161, 27, .07); border: 1px solid rgba(249, 161, 27, .3); border-radius: var(--r); padding: 22px 24px; margin: 34px 0; }
.jm-tldr h2 { margin: 0 0 10px !important; font-size: 1.02rem !important; color: var(--accent-ink); display: flex; align-items: center; gap: 9px; }
.jm-tldr p { margin: 0; font-size: .97rem; }
.jm-toc { background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 20px 24px; margin: 30px 0; }
.jm-toc b { display: block; margin-bottom: 10px; color: var(--text); font-size: .95rem; }
.jm-toc ol { margin: 0; padding-inline-start: 1.3em; font-size: .93rem; }
.jm-toc li { margin-bottom: 6px; }
.jm-toc a { color: var(--muted); text-decoration: none; }
.jm-toc a:hover { color: var(--accent-ink); }
.jm-art-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 760px; margin: 56px auto 0; }
@media (max-width: 640px) { .jm-art-nav { grid-template-columns: 1fr; } }
.jm-art-nav a { display: block; background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 18px 20px; transition: border-color .2s; }
.jm-art-nav a:hover { border-color: var(--border2); }
.jm-art-nav small { color: var(--faint); display: block; margin-bottom: 5px; font-weight: 600; }
.jm-art-nav span { color: var(--text); font-weight: 600; font-size: .93rem; line-height: 1.5; display: block; }
.jm-authbox { display: flex; gap: 22px; align-items: center; max-width: 760px; margin: 50px auto 0; background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 26px; flex-wrap: wrap; }
.jm-authbox img, .jm-authbox .jm-avatar { width: 84px; height: 84px; border-radius: 50%; object-fit: cover; flex: none; display: grid; place-items: center; background: var(--grad); color: var(--btn-text); font-weight: 700; font-size: 1.6rem; }
.jm-authbox h3 { margin: 0 0 4px; font-size: 1.1rem; }
.jm-authbox p { margin: 0; color: var(--muted); font-size: .92rem; }

/* ---------- forms ---------- */
.jm-form-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.jm-label { font-size: .88rem; font-weight: 700; color: var(--text); }
.jm-label small { color: var(--faint); font-weight: 500; }
.jm-input, .jm-select, .jm-textarea {
    width: 100%; background: var(--bg2); border: 1px solid var(--border); color: var(--text); border-radius: var(--r-sm);
    padding: 12px 14px; font-size: .95rem; font-family: inherit; transition: border-color .18s, box-shadow .18s; appearance: none; -webkit-appearance: none;
}
.jm-input::placeholder, .jm-textarea::placeholder { color: var(--faint); }
.jm-input:focus, .jm-select:focus, .jm-textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px rgba(249, 161, 27, .18); }
.jm-input.is-invalid, .jm-select.is-invalid, .jm-textarea.is-invalid, .jm-input[aria-invalid="true"] { border-color: var(--danger); box-shadow: 0 0 0 4px var(--danger-soft); }
.jm-textarea { min-height: 120px; resize: vertical; }
.jm-select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239fb0cc' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-inline-end: 38px; }
[dir="rtl"] .jm-select { background-position: left 12px center; }
.jm-input-wrap { position: relative; }
.jm-input-wrap > svg { position: absolute; top: 50%; inset-inline-start: 13px; transform: translateY(-50%); width: 18px; height: 18px; color: var(--faint); pointer-events: none; }
.jm-input-wrap > .jm-input { padding-inline-start: 42px; }
.jm-input-wrap > button { position: absolute; top: 50%; inset-inline-end: 8px; transform: translateY(-50%); background: none; border: 0; color: var(--faint); cursor: pointer; padding: 6px; border-radius: 8px; }
.jm-input-wrap > button:hover { color: var(--text); background: var(--card2); }
.jm-field-error { color: var(--danger); font-size: .82rem; font-weight: 600; display: none; }
.jm-field-error.is-visible, .jm-field-error:not(:empty) { display: block; }
.jm-help { color: var(--faint); font-size: .82rem; }
.jm-check { display: flex; align-items: flex-start; gap: 10px; font-size: .9rem; color: var(--muted); cursor: pointer; }
.jm-check input { width: 18px; height: 18px; margin-top: 3px; accent-color: var(--accent); flex: none; }
.jm-check a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
.jm-switch { position: relative; display: inline-block; width: 44px; height: 24px; flex: none; }
.jm-switch input { opacity: 0; width: 0; height: 0; }
.jm-switch span { position: absolute; inset: 0; border-radius: 999px; background: var(--card2); border: 1px solid var(--border); transition: .2s; cursor: pointer; }
.jm-switch span::before { content: ""; position: absolute; width: 18px; height: 18px; inset-inline-start: 2px; top: 2px; border-radius: 50%; background: var(--faint); transition: .2s; }
/* `~`, not `+`: Thymeleaf's th:field renders a hidden companion input straight
   after a checkbox, which an adjacent-sibling combinator would stop at — the
   switch would then never paint its "on" state. */
.jm-switch input:checked ~ span { background: var(--grad); border-color: transparent; }
.jm-switch input:checked ~ span::before { background: var(--btn-text); transform: translateX(20px); }
[dir="rtl"] .jm-switch input:checked ~ span::before { transform: translateX(-20px); }
.jm-divider { display: flex; align-items: center; gap: 14px; color: var(--faint); font-size: .82rem; margin: 20px 0; }
.jm-divider::before, .jm-divider::after { content: ""; flex: 1; border-top: 1px solid var(--border); }

/* ---------- alerts / status ---------- */
.jm-alert { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border-radius: 12px; border: 1px solid var(--border); background: var(--card); color: var(--text); font-size: .92rem; margin-bottom: 18px; }
.jm-alert svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }
.jm-alert p { margin: 0; }
.jm-alert--success { background: var(--success-soft); border-color: var(--success-border); color: var(--success); }
.jm-alert--error, .jm-alert--danger { background: var(--danger-soft); border-color: var(--danger-border); color: var(--danger); }
.jm-alert--warning { background: var(--warn-soft); border-color: var(--warn-border); color: var(--warn); }
.jm-alert--info { background: var(--cyan-soft); border-color: var(--cyan-border); color: var(--cyan); }
.jm-alert .jm-alert-close { margin-inline-start: auto; background: none; border: 0; color: inherit; cursor: pointer; opacity: .7; padding: 0 2px; }
.jm-alert .jm-alert-close:hover { opacity: 1; }
.jm-status { max-width: 640px; margin: 60px auto; text-align: center; background: var(--card); border: 1px solid var(--border); border-radius: 22px; padding: 48px 34px; }
.jm-status-icon { width: 84px; height: 84px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto 22px; }
.jm-status-icon svg { width: 40px; height: 40px; }
.jm-status-icon--success { background: var(--success-soft); color: var(--success); border: 1px solid var(--success-border); }
.jm-status-icon--warning { background: var(--warn-soft); color: var(--warn); border: 1px solid var(--warn-border); }
.jm-status-icon--danger { background: var(--danger-soft); color: var(--danger); border: 1px solid var(--danger-border); }
.jm-status-icon--info { background: var(--cyan-soft); color: var(--cyan); border: 1px solid var(--cyan-border); }
.jm-status h1 { font-size: clamp(1.5rem, 3vw, 2rem); margin: 0 0 12px; }
.jm-status p { color: var(--muted); margin: 0 0 8px; }
.jm-status .jm-cta-row { margin-top: 28px; }
.jm-status dl { display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; text-align: start; margin: 24px 0 0; padding: 18px; background: var(--bg2); border: 1px solid var(--border); border-radius: 14px; font-size: .9rem; }
.jm-status dt { color: var(--faint); font-weight: 600; }
.jm-status dd { margin: 0; color: var(--text); font-weight: 600; }

/* ---------- pagination ---------- */
.jm-pagination { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 44px; flex-wrap: wrap; }
.jm-pagination a, .jm-pagination span { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; height: 40px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--card); color: var(--muted); font-weight: 700; font-size: .9rem; }
.jm-pagination a:hover { border-color: var(--border2); color: var(--text); }
.jm-pagination [aria-current] { background: var(--grad); color: var(--btn-text); border-color: transparent; }
.jm-pagination .is-disabled { opacity: .45; pointer-events: none; }

/* ---------- tabs ---------- */
.jm-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
.jm-tabs::-webkit-scrollbar { display: none; }
.jm-tabs a, .jm-tabs button { padding: 12px 16px; border: 0; background: none; color: var(--muted); font-weight: 700; font-size: .92rem; cursor: pointer; white-space: nowrap; position: relative; font-family: inherit; }
.jm-tabs a:hover, .jm-tabs button:hover { color: var(--text); }
.jm-tabs [aria-current], .jm-tabs [aria-selected="true"], .jm-tabs .is-active { color: var(--text); }
.jm-tabs [aria-current]::after, .jm-tabs [aria-selected="true"]::after, .jm-tabs .is-active::after { content: ""; position: absolute; inset-inline: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--grad); }

/* ---------- modal ---------- */
.jm-modal { position: fixed; inset: 0; z-index: 150; display: none; align-items: center; justify-content: center; padding: 20px; }
.jm-modal.is-open, .jm-modal[data-open="true"] { display: flex; }
.jm-modal-backdrop { position: absolute; inset: 0; background: rgba(3, 6, 15, .7); backdrop-filter: blur(4px); }
.jm-modal-panel { position: relative; width: 100%; max-width: 560px; max-height: calc(100vh - 40px); overflow-y: auto; background: var(--bg2); color: var(--text); border: 1px solid var(--border); border-radius: 20px; box-shadow: var(--shadow); padding: 28px; }
.jm-modal-panel--lg { max-width: 900px; }
/* The preview modal is the main way a visitor evaluates the course, so it gets close to the whole
   viewport rather than a 960px box. clamp keeps it from becoming a letterbox on ultra-wide screens. */
.jm-modal-panel--video {
    max-width: min(1500px, 94vw); width: 94vw; padding: 0; overflow: hidden;
    background: #05070d; border-radius: 18px;
    box-shadow: 0 50px 120px -30px rgba(0, 0, 0, .75);
}
.jm-modal-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.jm-modal-head h2, .jm-modal-head h3 { margin: 0; font-size: 1.15rem; flex: 1; }
.jm-modal-close { background: var(--card); border: 1px solid var(--border); color: var(--muted); width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; cursor: pointer; }
.jm-modal-close:hover { color: var(--text); border-color: var(--border2); }
.jm-modal-close svg { width: 18px; height: 18px; }
.jm-modal-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; flex-wrap: wrap; }

/* ---------- auth pages ---------- */
.jm-auth { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }
@media (max-width: 960px) { .jm-auth { grid-template-columns: 1fr; } .jm-auth-brand { display: none; } }
.jm-auth-brand { position: relative; overflow: hidden; background: var(--bg2); border-inline-end: 1px solid var(--border); display: flex; flex-direction: column; justify-content: center; padding: 60px 56px; }
.jm-auth-brand .jm-hero-bg { z-index: 0; }
.jm-auth-brand > * { position: relative; z-index: 1; }
.jm-auth-brand h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); line-height: 1.3; margin: 26px 0 14px; max-width: 18ch; }
.jm-auth-brand p { color: var(--muted); max-width: 40ch; margin: 0 0 26px; font-size: 1.02rem; }
.jm-auth-brand .jm-code-float { position: absolute; }
.jm-auth-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.jm-auth-points li { display: flex; align-items: center; gap: 12px; color: var(--text); font-weight: 600; font-size: .95rem; }
.jm-auth-points svg { width: 20px; height: 20px; color: var(--accent-ink); flex: none; }
.jm-auth-main { display: flex; flex-direction: column; padding: 24px 24px 40px; }
.jm-auth-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 30px; }
.jm-auth-card { width: 100%; max-width: 440px; margin: auto; }
.jm-auth-card h1 { font-size: 1.7rem; margin: 0 0 8px; line-height: 1.3; }
.jm-auth-card > p { color: var(--muted); margin: 0 0 26px; }
.jm-auth-foot { text-align: center; color: var(--muted); font-size: .92rem; margin-top: 22px; }
.jm-auth-foot a { color: var(--accent-ink); font-weight: 700; }
.jm-oauth { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 13px 18px; border-radius: 13px; border: 1px solid var(--border); background: var(--card); color: var(--text); font-weight: 700; font-size: .95rem; text-decoration: none; transition: .18s; }
.jm-oauth:hover { border-color: var(--faint); background: var(--card2); color: var(--text); }
.jm-oauth svg { width: 20px; height: 20px; }

/* ---------- footer ---------- */
.jm-footer { border-top: 1px solid var(--hdr-border); background: linear-gradient(180deg, transparent, var(--card)); margin-top: 40px; }
.jm-ft { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: 38px; padding: 58px 0 44px; }
@media (max-width: 920px) { .jm-ft { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .jm-ft { grid-template-columns: 1fr; } }
.jm-ft h3 { font-size: .92rem; font-weight: 700; color: var(--text); margin: 0 0 16px; }
.jm-ft ul { list-style: none; margin: 0; padding: 0; }
.jm-ft li { margin-bottom: 10px; }
.jm-ft a { color: var(--muted); font-size: .92rem; }
.jm-ft a:hover { color: var(--accent-ink); }
.jm-ft .jm-about-f { color: var(--muted); font-size: .92rem; margin: 14px 0 18px; max-width: 34ch; }
.jm-ft .jm-logo img { height: 48px; }
.jm-ft form { display: flex; gap: 8px; margin-top: 12px; }
.jm-ft form .jm-input { padding: 10px 12px; font-size: .88rem; }
.jm-legal { border-top: 1px solid var(--hdr-border); padding: 20px 0; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; color: var(--faint); font-size: .85rem; }
.jm-legal a { color: var(--muted); }
.jm-legal a:hover { color: var(--accent-ink); }

/* ---------- misc ---------- */
.jm-reveal { opacity: 0; transform: translateY(22px); transition: opacity .6s, transform .6s; }
.jm-reveal.in { opacity: 1; transform: none; }
html.no-animations .jm-reveal { opacity: 1; transform: none; transition: none; }
.jm-center { text-align: center; }
.jm-mt { margin-top: 34px; }
.jm-muted { color: var(--muted); }
.jm-faint { color: var(--faint); }
.jm-empty { text-align: center; padding: 60px 20px; color: var(--muted); background: var(--card); border: 1px dashed var(--border); border-radius: var(--r); }
.jm-empty svg { width: 46px; height: 46px; color: var(--faint); margin: 0 auto 14px; }
.jm-err { min-height: 62vh; display: grid; place-items: center; text-align: center; padding: 60px 0; }
.jm-err .jm-code { font-family: var(--mono); font-size: clamp(4rem, 14vw, 7.5rem); font-weight: 700; line-height: 1; background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.jm-err h1 { font-size: clamp(1.4rem, 3vw, 2rem); margin: 10px 0 8px; }
.jm-err p { color: var(--muted); margin: 0 0 26px; }
.jm-wa-fab { position: fixed; bottom: 18px; inset-inline-end: 18px; z-index: 90; display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--wa); color: #fff; box-shadow: 0 12px 30px -8px rgba(34, 197, 94, .65); transition: transform .2s; }
.jm-wa-fab:hover { transform: scale(1.08); color: #fff; }
.jm-wa-fab svg { width: 26px; height: 26px; }

/* Free-consultation CTA (fragments/consultation-cta.html).
   --labelled grows the circle into a pill on hover/focus; on touch, where there is no hover,
   the icon stands alone and the accessible name comes from aria-label. */
.jm-wa-fab--labelled { grid-auto-flow: column; width: auto; height: 56px; padding-inline: 15px; border-radius: 999px; }
.jm-wa-fab__label {
    max-width: 0; margin-inline-start: 0; overflow: hidden; white-space: nowrap; opacity: 0;
    font-weight: 700; font-size: .92rem;
    transition: max-width .3s ease, opacity .22s ease, margin-inline-start .3s ease;
}
.jm-wa-fab--labelled:hover .jm-wa-fab__label,
.jm-wa-fab--labelled:focus-visible .jm-wa-fab__label { max-width: 240px; margin-inline-start: 10px; opacity: 1; }
/* Expanding instead of scaling keeps the label crisp */
.jm-wa-fab--labelled:hover { transform: none; }
/* Attention ring radiating out of the bubble; honours the admin animations toggle and reduced motion.
   It shares the bubble's green and paints over its background, so only the part that grows past the
   edge reads as a ring. The icon and label are positioned so they stay above it. */
.jm-wa-fab__pulse {
    position: absolute; inset: 0; border-radius: inherit; background: var(--wa);
    animation: jm-wa-pulse 2.4s ease-out infinite; pointer-events: none;
}
.jm-wa-fab__glyph, .jm-wa-fab__label { position: relative; }
@keyframes jm-wa-pulse {
    0% { transform: scale(1); opacity: .5; }
    70% { transform: scale(1.5); opacity: 0; }
    100% { transform: scale(1.5); opacity: 0; }
}
html.no-animations .jm-wa-fab__pulse { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) { .jm-wa-fab__pulse { animation: none; opacity: 0; } }

/* Hero variant of the same CTA: WhatsApp-tinted jm-btn so it reads as a chat action
   without competing with the primary gradient button. */
/* Free-consultation CTA. Solid WhatsApp green with a matching glow: as a faint tint it read as a
   disabled third option next to the gradient primary, which is the opposite of the intent. */
.jm-btn-wa {
    background: linear-gradient(135deg, #25d366, #15a64a);
    border-color: transparent; color: #06240f;
    box-shadow: 0 10px 26px -10px rgba(34, 197, 94, .6);
}
.jm-btn-wa:hover {
    background: linear-gradient(135deg, #2ee070, #19b352);
    color: #06240f; transform: translateY(-2px);
    box-shadow: 0 16px 34px -12px rgba(34, 197, 94, .72);
}
.jm-btn-wa:active { transform: translateY(0); }
/* The glyph gets a soft disc so the mark stays legible on the green. */
.jm-btn-wa svg { border-radius: 50%; }
html.dark .jm-btn-wa { color: #04170a; }
.jm-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.jm-table th, .jm-table td { padding: 12px 14px; border-bottom: 1px solid var(--border); text-align: start; }
.jm-table th { color: var(--faint); font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 700; }
.jm-table tr:hover td { background: var(--card); }
.jm-kbd { font-family: var(--mono); font-size: .8em; background: var(--card2); border: 1px solid var(--border); border-radius: 6px; padding: 1px 6px; }
.jm-toast-anchor { position: fixed; bottom: 20px; inset-inline-start: 20px; z-index: 200; }
.jm-bidi { unicode-bidi: plaintext; }
@media (prefers-reduced-motion: reduce) {
    body.jm-site *, body.jm-site *::before, body.jm-site *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
.jm-help--success { color: var(--success); font-weight: 600; margin-top: 10px; }
.jm-help--error { color: var(--danger); font-weight: 600; margin-top: 10px; }
.jm-cprogress { display: grid; gap: 8px; margin-top: 8px; }
.jm-cactions form { flex: 1; display: flex; }
.jm-cactions form .jm-btn { width: 100%; }

/* ---------- home-page specifics ---------- */
.jm-code-float--1 { top: 120px; inset-inline-start: 6%; }
.jm-code-float--2 { top: 250px; inset-inline-start: 3%; }
.jm-code-float--3 { top: 130px; inset-inline-end: 6%; }
.jm-code-float--4 { top: 265px; inset-inline-end: 4%; }
.jm-filter { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: -16px 0 30px; }
.jm-tcard blockquote { margin: 0; }
.jm-tcard figcaption > span { min-width: 0; }
.jm-course-item { display: contents; }

/* ---------- catalog toolbar ---------- */
.jm-crumbs--center { justify-content: center; margin-bottom: 18px; }
/* A hero reduced to a chip strip, once the breadcrumb/eyebrow/title/lede came out: keeps the glow as a
   transition under the header but not the height a full header needed. Used by /subscriptions. */
.jm-hero--strip { padding: 26px 0 14px; }
.jm-hero--strip .jm-meta-row { margin-top: 0; }
.jm-hero--compact h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); margin-top: 18px; }
.jm-hero--compact .jm-lead { margin-bottom: 0; }
.jm-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 18px; }
.jm-toolbar__search { flex: 1 1 320px; max-width: 460px; }
.jm-toolbar__side { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.jm-select--inline { width: auto; padding-block: 10px; }
.jm-filter--start { justify-content: flex-start; margin: 0 0 26px; }
.jm-pagination-wrap { margin-top: 40px; display: grid; gap: 10px; }
.jm-pagination-wrap .jm-pagination { margin-top: 0; }
.jm-empty h2 { font-size: 1.15rem; margin: 0 0 6px; color: var(--text); }
.jm-empty p { margin: 0; }

/* ---------- blog (index + article) ---------- */
.jm-bcard > .jm-bbody { display: flex; flex-direction: column; gap: 12px; flex: 1; }
.jm-bcard .jm-cthumb { border-bottom: 1px solid var(--border); }
.jm-bcard:hover .jm-cthumb img { transform: scale(1.045); }
.jm-bmeta span { display: inline-flex; align-items: center; gap: 5px; }
.jm-bmeta svg { width: 14px; height: 14px; }
.jm-bcard .jm-bmeta { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border); }
.jm-btag--accent { color: var(--accent-ink); background: rgba(249, 161, 27, .1); border-color: rgba(249, 161, 27, .3); }
a.jm-btag:hover { color: var(--accent-ink); border-color: var(--border2); }
.jm-art-col { max-width: 760px; margin-inline: auto; }
.jm-art-meta > span, .jm-art-meta > time { display: inline-flex; align-items: center; gap: 8px; }
.jm-art-meta svg { width: 16px; height: 16px; flex: none; }
/* Article FAQ (under the body): reuses the .jm-faq accordion of the course page. */
.jm-art-faq { margin-top: 48px; scroll-margin-top: calc(90px + var(--ann-bar-h, 0px)); }
.jm-art-faq > h2 { font-size: 1.5rem; margin: 0 0 18px; }
.jm-art-foot { max-width: 760px; margin: 40px auto 0; padding-top: 22px; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 18px; }
.jm-art-foot .jm-soc { margin-top: 0; }
.jm-art-foot-label { display: block; color: var(--faint); font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 8px; }
.jm-authbox > div { flex: 1; min-width: 200px; }
.jm-authbox small { display: block; color: var(--faint); font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 4px; }
.jm-toc[hidden] { display: none; }
.jm-toc a.is-active { color: var(--accent-ink); }
.jm-prose :is(h2, h3)[id] { scroll-margin-top: calc(90px + var(--ann-bar-h, 0px)); }

/* ---------- students reviews ---------- */
.jm-tcard--reveal { break-inside: avoid; }
.jm-vthumb { width: 100%; padding: 0; border: 0; cursor: pointer; font: inherit; color: inherit; text-align: start; }
.jm-vthumb .jm-play span { width: 58px; height: 58px; }
.jm-vthumb .jm-play svg { width: 24px; height: 24px; }
[dir="rtl"] .jm-vthumb .jm-play svg { transform: scaleX(-1); }
.jm-vduration { position: absolute; bottom: 10px; inset-inline-end: 10px; z-index: 2; font-family: var(--mono); font-size: .74rem; font-weight: 700; color: #fff; background: rgba(3, 6, 15, .7); border: 1px solid rgba(255, 255, 255, .14); border-radius: 6px; padding: 2px 8px; direction: ltr; }
.jm-video-player { position: relative; aspect-ratio: 16 / 9; width: 100%; background: #000; }
.jm-video-player iframe, .jm-video-player video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
.jm-modal-close--float { position: absolute; top: 10px; inset-inline-end: 10px; z-index: 3; background: rgba(3, 6, 15, .6); border-color: rgba(255, 255, 255, .16); color: #fff; }
.jm-modal-close--float:hover { color: #fff; background: rgba(3, 6, 15, .85); }

/* ---------- certificate verify ---------- */
.jm-verify { max-width: 640px; margin-inline: auto; }
.jm-input--code { font-family: var(--mono); text-align: center; letter-spacing: .12em; font-size: 1.1rem; direction: ltr; }
.jm-verify .jm-status { margin: 22px 0 0; padding: 34px 26px; }
.jm-verify .jm-status-icon { width: 64px; height: 64px; margin-bottom: 16px; }
.jm-verify .jm-status-icon svg { width: 30px; height: 30px; }
.jm-verify .jm-status h2 { font-size: 1.3rem; margin: 0 0 6px; }
.jm-spin { animation: jm-spin 1s linear infinite; }
@keyframes jm-spin { to { transform: rotate(360deg); } }
.jm-verify [hidden] { display: none !important; }
.jm-toc ol { list-style: decimal; }
.jm-art-meta small { display: block; font-size: .76rem; line-height: 1.2; }
.jm-art-img[hidden] { display: none; }

/* ---------- side layout (bundle detail, discounts apply) ---------- */
.jm-side-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 34px; align-items: start; }
.jm-side-layout__main { display: grid; gap: 26px; min-width: 0; }
.jm-side-layout__aside { position: sticky; top: calc(90px + var(--ann-bar-h, 0px)); display: grid; gap: 14px; }
@media (max-width: 1023px) {
    .jm-side-layout { grid-template-columns: 1fr; }
    .jm-side-layout__aside { position: static; }
}
.jm-chero > .jm-wrap { position: relative; }
.jm-pane .jm-learn { padding: 0; margin: 4px 0 0; }
.jm-pane .jm-prose { color: var(--prose); }
.jm-pane--stack { display: grid; gap: 14px; }
.jm-mobile-cta .jm-price-row { display: flex; align-items: baseline; gap: 10px; flex: 1; min-width: 0; }
.jm-modal.flex:not(.hidden) { display: flex; }

/* ---------- pricing tiers (subscriptions catalog) ---------- */
.jm-tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 380px)); justify-content: center; gap: 26px; align-items: stretch; }
.jm-tier { position: relative; display: flex; flex-direction: column; gap: 14px; overflow: visible; transition: transform .22s, border-color .22s, box-shadow .22s; }
.jm-tier:hover { transform: translateY(-4px); border-color: var(--border2); box-shadow: var(--shadow); }
.jm-tier--popular { border-color: var(--border2); box-shadow: var(--glow); }
.jm-tier__badge { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); white-space: nowrap; box-shadow: var(--glow); }
.jm-tier__media { margin: -6px 0 4px; }
.jm-tier__media .jm-cthumb { border-radius: var(--r-sm); border: 1px solid var(--border); }
.jm-tier h2 { margin: 0; font-size: 1.25rem; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.jm-tier h2 .jm-chip { font-size: .74rem; padding: 3px 11px; }
.jm-tier__scope { display: flex; flex-wrap: wrap; gap: 8px; }
.jm-tier__scope .jm-chip { font-size: .76rem; padding: 4px 11px; }
.jm-tier .jm-price-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-top: 6px; }
.jm-tier .jm-price--lg { font-size: 2.3rem; line-height: 1.1; letter-spacing: -.5px; }
.jm-tier__period { font-size: .9rem; font-weight: 600; }
.jm-tier__period::before { content: "/ "; }
.jm-tier__features { flex: 1; }
.jm-tier .jm-tier__includes-title { font-size: .76rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); margin: 0 0 10px; padding-top: 16px; border-top: 1px solid var(--border); }
.jm-tier .jm-includes { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; font-size: .92rem; color: var(--muted); }
.jm-tier .jm-includes li { display: flex; align-items: flex-start; gap: 10px; }
.jm-tier .jm-includes svg { width: 17px; height: 17px; color: var(--accent-ink); flex: none; margin-top: 3px; }
.jm-tier__cta { margin-top: auto; padding-top: 18px; display: grid; gap: 10px; }
.jm-tier .jm-alert { margin: 0; font-size: .86rem; }
.jm-tier .jm-check { padding: 10px 12px; border: 1px solid var(--warn-border); background: var(--warn-soft); border-radius: var(--r-sm); }

/* ---------- discounts ---------- */
.jm-ficon--num { font-weight: 700; font-size: 1.3rem; font-family: var(--mono); }
.jm-alert__title { margin: 0 0 4px; font-size: 1rem; font-weight: 700; display: block; color: inherit; }
.jm-alert__sub { font-weight: 500; opacity: .8; }
.jm-alert > div { min-width: 0; flex: 1; }
.jm-file { padding: 9px 12px; cursor: pointer; }
.jm-file::file-selector-button { font-family: inherit; font-weight: 700; font-size: .82rem; color: var(--accent-ink); background: rgba(249, 161, 27, .12); border: 1px solid rgba(249, 161, 27, .3); border-radius: 8px; padding: 6px 12px; margin-inline-end: 12px; cursor: pointer; }
.jm-drop { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; height: 150px; border: 2px dashed var(--border); border-radius: var(--r-sm); background: var(--bg2); color: var(--faint); font-size: .82rem; font-weight: 600; cursor: pointer; overflow: hidden; transition: border-color .18s, color .18s, background .18s; }
.jm-drop:hover, .jm-drop:focus-within { border-color: var(--accent); color: var(--accent-ink); background: var(--card); }
.jm-drop svg { width: 30px; height: 30px; }
.jm-drop img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.jm-drop.dsc-drop--filled { border-style: solid; border-color: var(--border2); padding: 0; }
.jm-identity { align-items: flex-start; }
.jm-identity__body { display: grid; gap: 14px; }
.jm-identity__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.jm-identity__head p { color: inherit; opacity: .85; }
.jm-identity__docs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.jm-identity__docs img { width: 100%; height: 110px; object-fit: cover; border-radius: 10px; border: 1px solid var(--success-border); display: block; }
.jm-identity__facts { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0; font-size: .88rem; }
.jm-identity__facts > div { display: flex; gap: 6px; }
.jm-identity__facts dt { opacity: .8; }
.jm-identity__facts dd { margin: 0; font-weight: 700; }
.jm-history__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.jm-history__item { border: 1px solid var(--border); border-radius: var(--r-sm); padding: 14px 16px; background: var(--bg2); display: grid; gap: 6px; }
.jm-history__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.jm-history__head b { font-size: .92rem; color: var(--text); min-width: 0; }
.jm-history__head .jm-chip { font-size: .72rem; padding: 3px 10px; flex: none; }
.jm-history__note { margin: 4px 0 0; padding: 10px 12px; border-radius: 9px; background: var(--card); font-size: .82rem; color: var(--muted); }
.jm-history__note span:first-child { font-weight: 700; color: var(--text); }
.jm-history__code { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.jm-history__code .jm-kbd { font-size: .85rem; font-weight: 700; color: var(--success); background: var(--success-soft); border-color: var(--success-border); padding: 5px 10px; letter-spacing: .04em; }
/* Searchable combobox (searchable-select.js) — token overrides of the legacy public-pages.css skin */
body.jm-site .dsc-combobox-btn { background: var(--bg2); border: 1px solid var(--border); color: var(--text); border-radius: var(--r-sm); padding: 12px 14px; font-size: .95rem; box-shadow: none; font-family: inherit; }
body.jm-site .dsc-combobox-btn:hover { border-color: var(--faint); }
body.jm-site .dsc-combobox-btn:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(249, 161, 27, .18); outline: none; }
body.jm-site .dsc-native-select.is-invalid + .dsc-combobox .dsc-combobox-btn { border-color: var(--danger); box-shadow: 0 0 0 4px var(--danger-soft); }
body.jm-site .dsc-combobox-label { color: var(--text); }
body.jm-site .dsc-combobox-label.is-placeholder, body.jm-site .dsc-combobox-chev { color: var(--faint); }
body.jm-site .dsc-combobox-pop { background: var(--bg2); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); }
body.jm-site .dsc-combobox-search { background: transparent; color: var(--text); border-bottom: 1px solid var(--border); font-family: inherit; }
body.jm-site .dsc-combobox-search::placeholder { color: var(--faint); }
body.jm-site .dsc-combobox-group { color: var(--faint); }
body.jm-site .dsc-combobox-opt { color: var(--text); }
body.jm-site .dsc-combobox-opt:hover, body.jm-site .dsc-combobox-opt.is-active { background: rgba(249, 161, 27, .12); color: var(--accent-ink); }

/* ---------- course detail page ---------- */
.jm-chero .jm-crumbs { margin-bottom: 26px; }
.jm-chero__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.jm-chero h1 { margin-top: 16px; }
.jm-meta-chip b { color: var(--text); font-weight: 700; }
.jm-meta-chip small { color: var(--faint); font-size: .8rem; }
a.jm-meta-chip { transition: border-color .18s, color .18s; }
a.jm-meta-chip:hover { border-color: var(--border2); color: var(--text); }
.jm-meta-chip--rating svg { color: var(--accent2); }
.jm-byline { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.jm-byline img, .jm-byline .jm-avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; object-position: top; display: grid; place-items: center; background: var(--grad); color: var(--btn-text); font-weight: 700; flex: none; }
.jm-byline small { display: block; color: var(--faint); font-size: .78rem; line-height: 1.3; }
.jm-byline b { color: var(--text); font-size: .95rem; }
.jm-cimg img { height: auto; }
.jm-cimg__ph { aspect-ratio: 16 / 9; display: grid; place-items: center; color: var(--faint); background: linear-gradient(135deg, var(--card2), var(--thumb-bg)); }
.jm-cimg__ph svg { width: 56px; height: 56px; }
@media (max-width: 880px) { .jm-chero .jm-cimg { order: -1; } .jm-chero { padding-top: 26px; } }

/* two-column body */
.jm-cdetail { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 44px; align-items: stretch; }
.jm-cdetail__main { display: grid; gap: 56px; min-width: 0; }
.jm-cdetail__side { min-width: 0; }
.jm-cdetail .jm-learn, .jm-cdetail .jm-two, .jm-cdetail .jm-inst { max-width: none; margin-inline: 0; }
@media (max-width: 1023px) {
    .jm-cdetail { grid-template-columns: 1fr; gap: 40px; }
    .jm-cdetail__side { order: -1; }
    .jm-cdetail .jm-pricing { position: static; max-height: none; overflow: visible; }
}
/* Desktop: the card never scrolls inside itself. A card taller than the window sticks by its BOTTOM
   edge instead (sticky-card.js publishes its height as --jm-pricing-h), so it travels with the page
   until its last line is on screen. Without the script the height reads 0 and it sticks at the top. */
@media (min-width: 1024px) {
    .jm-pricing {
        overflow: hidden;
        top: min(calc(90px + var(--ann-bar-h, 0px)), calc(100vh - var(--jm-pricing-h, 0px) - 24px));
    }
}
.jm-ctitle { display: flex; align-items: center; gap: 10px; font-size: clamp(1.25rem, 2.4vw, 1.5rem); line-height: 1.35; margin: 0 0 18px; letter-spacing: -.2px; }
.jm-ctitle svg { width: 22px; height: 22px; color: var(--accent-ink); flex: none; }
.jm-chead-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.jm-chead-row .jm-ctitle { margin: 0 0 4px; }
.jm-curr__sum { margin: 0; color: var(--muted); font-size: .9rem; }

/* curriculum accordion */
/* Curriculum. The section header and the lecture rows used to share one --card surface, which made
   the two levels indistinguishable. Now the header is a distinct band and the lecture list sits on the
   lighter page surface, so the hierarchy is "container → header → contents" at a glance. */
.jm-curr { display: grid; gap: 12px; }
.jm-curr__sec {
    border: 1px solid var(--border); border-radius: 14px; background: var(--bg2);
    overflow: hidden; transition: border-color .2s, box-shadow .2s;
}
/* Driven by the `is-open` class that course-landing.js toggles, not by :has(). An earlier :has()
   version matched the element (sec.matches() returned true) yet never restyled it in the browser, so
   the open state silently looked identical to the closed one. The accordion JS already owns this
   state — taking the class from it is both reliable and works without :has() support. */
.jm-curr__sec.is-open {
    border-color: var(--border2); box-shadow: 0 10px 30px -22px rgba(15, 23, 42, .4);
}

/* --- header band --- */
.jm-curr__head {
    width: 100%; display: flex; align-items: center; gap: 12px; padding: 15px 18px;
    background: var(--card); border: 0; border-bottom: 1px solid transparent; cursor: pointer;
    color: var(--text); font-family: inherit; font-weight: 700; font-size: .98rem;
    text-align: start; line-height: 1.4; transition: background .18s, border-color .18s;
}
.jm-curr__head:hover { background: var(--card2); }
/* Once open, the header is visibly the lid of the list below it. Targets the button's own
   aria-expanded — the button IS the header, so this needs no parent selector at all.
   The distinction is carried by a solid accent rail and a real divider rather than by a 0.035 -> 0.07
   alpha shift: that difference is barely perceptible, and it made "open" and "closed" look identical
   in practice. A rail reads instantly at any contrast or zoom level. */
.curriculum-toggle[aria-expanded="true"].jm-curr__head {
    background: var(--card2);
    border-bottom-color: var(--border);
    box-shadow: inset 3px 0 0 0 var(--accent), inset 0 -1px 0 0 var(--border);
}
[dir="rtl"] .curriculum-toggle[aria-expanded="true"].jm-curr__head {
    box-shadow: inset -3px 0 0 0 var(--accent), inset 0 -1px 0 0 var(--border);
}
/* The number chip switches to the solid accent when its section is open. */
.curriculum-toggle[aria-expanded="true"] .jm-curr__num {
    background: var(--grad); color: var(--btn-text);
}
.jm-curr__head b { flex: 1; min-width: 0; }
.jm-curr__head small { color: var(--muted); font-weight: 600; font-size: .8rem; white-space: nowrap; }
.jm-curr__chev { width: 18px; height: 18px; color: var(--accent-ink); flex: none; transition: transform .25s; }
.curriculum-toggle[aria-expanded="true"] .jm-curr__chev { transform: rotate(180deg); }
/* Numbered chip, so sections are countable without reading the titles. */
.jm-curr__num {
    flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px;
    background: rgba(249, 161, 27, .13); color: var(--accent-ink);
    font-size: .8rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* --- lecture rows: hairline-separated, on the lighter surface --- */
.jm-curr__list { list-style: none; margin: 0; padding: 4px 6px; display: grid; gap: 0; }
.jm-curr__item {
    display: flex; align-items: center; gap: 11px; padding: 11px 12px; border-radius: 9px;
    font-size: .92rem; color: var(--muted); transition: background .16s;
}
.jm-curr__item + .jm-curr__item { box-shadow: inset 0 1px 0 var(--border); }
.jm-curr__item > svg { width: 17px; height: 17px; color: var(--faint); flex: none; }
.jm-curr__title { min-width: 0; flex: 1; }
/* A free preview is the actionable row, so it gets full-strength text and an accent rail on hover. */
.jm-curr__item.preview-lecture { cursor: pointer; color: var(--text); font-weight: 500; position: relative; }
.jm-curr__item.preview-lecture:hover,
.jm-curr__item.preview-lecture:focus-visible { background: var(--card); }
.jm-curr__item.preview-lecture:hover::before {
    content: ""; position: absolute; inset-block: 6px; inset-inline-start: 0; width: 3px;
    border-radius: 0 3px 3px 0; background: var(--grad);
}
[dir="rtl"] .jm-curr__item.preview-lecture:hover::before { border-radius: 3px 0 0 3px; }
.jm-curr__item.preview-lecture > svg { color: var(--accent-ink); }
.jm-curr__end { margin-inline-start: auto; display: flex; align-items: center; gap: 8px; flex: none; }
.jm-curr__dur { color: var(--faint); font-size: .78rem; }
.jm-tag { display: inline-flex; align-items: center; gap: 4px; font-size: .72rem; font-weight: 700; padding: 2px 9px; border-radius: 999px; background: var(--card2); color: var(--muted); border: 1px solid var(--border); line-height: 1.5; white-space: nowrap; }
.jm-tag svg { width: 12px; height: 12px; }
.jm-tag--accent { color: var(--accent-ink); background: rgba(249, 161, 27, .1); border-color: rgba(249, 161, 27, .3); }
.jm-tag--cyan { color: var(--cyan); background: var(--cyan-soft); border-color: var(--cyan-border); }
.jm-tag--success { color: var(--success); background: var(--success-soft); border-color: var(--success-border); }
.jm-cdetail .jm-band { margin-top: 8px; }

/* pricing card */
.jm-pricing { display: grid; gap: 14px; align-content: start; }
.jm-pricing .jm-price-row { margin-bottom: 0; }
.jm-pricing .jm-alert { margin-bottom: 0; }
.jm-pricing .jm-includes { margin-top: 4px; }
.jm-includes__title b { color: var(--text); font-size: .92rem; }
.jm-coupon { display: grid; gap: 6px; }
.jm-coupon__row { display: flex; gap: 8px; }
.jm-coupon__row .jm-input { padding: 10px 12px; font-size: .9rem; min-width: 0; flex: 1; }
.jm-coupon__row .jm-btn { flex: none; }
.jm-coupon__row .jm-btn.is-applied { background: var(--success-soft); border-color: var(--success-border); color: var(--success); }
.jm-coupon__msg { margin-top: 6px; font-size: .85rem; }
.jm-coupon__msg .jm-alert { margin: 0; padding: 10px 12px; font-size: .85rem; }
.jm-coupon__msg .jm-alert p { margin: 0; }
.jm-coupon__msg .jm-alert p + p { margin-top: 2px; }
.jm-check--boxed, .jm-pricing .jm-check { padding: 10px 12px; border: 1px solid var(--warn-border); background: var(--warn-soft); border-radius: 12px; color: var(--text); }
.jm-cta-stack { display: grid; gap: 8px; }
.jm-pricing__subs { display: grid; gap: 8px; }
.jm-pricing__subs .jm-divider { margin: 4px 0 6px; text-align: center; }
/* "Or buy this course only": the card's grid gap already spaces it — the divider's own 20px margin doubled it */
.jm-pricing__body > .jm-divider { margin: 0; }
.jm-pricing__subprice { text-align: center; margin: 0; line-height: 1.6; }
.jm-pricing__subprice .jm-price { font-size: .95rem; }

/* mobile CTA bar */
.jm-mobile-cta__price { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.jm-mobile-cta__price .jm-price { font-size: 1.15rem; }
.jm-mobile-cta__price .jm-price-old { font-size: .78rem; }
.jm-mobile-cta__act { margin-inline-start: auto; display: flex; gap: 8px; flex: 1; justify-content: flex-end; min-width: 0; }
.jm-mobile-cta__act form { flex: 1; display: flex; justify-content: flex-end; }
.jm-mobile-cta__act .jm-btn { padding: 13px 20px; flex: 1; max-width: 320px; }

/* video preview modal */
.jm-modal-panel--video { position: relative; }
.jm-modal-panel--video .jm-modal-close { position: absolute; top: 10px; inset-inline-end: 10px; z-index: 2; background: rgba(7, 11, 23, .6); border-color: rgba(255, 255, 255, .15); color: #fff; }
.jm-vmodal { display: grid; grid-template-columns: minmax(0, 1fr) 360px; background: #05070d; }
.jm-vmodal__player { display: grid; align-items: center; background: #000; min-height: 220px; }
/* The player drives the height: 16/9 capped so a tall window never pushes the playlist off-screen. */
.jm-vmodal__player > div { width: 100%; aspect-ratio: 16 / 9; max-height: calc(100vh - 48px); }
.jm-vmodal__player iframe { width: 100%; height: 100%; border: 0; display: block; }

.jm-vmodal__side {
    background: var(--bg2); color: var(--text); border-inline-start: 1px solid var(--border);
    display: flex; flex-direction: column; max-height: calc(100vh - 48px);
}
.jm-vmodal__head {
    display: flex; align-items: center; gap: 10px; padding: 18px 20px 16px;
    border-bottom: 1px solid var(--border); padding-inline-end: 60px;
}
.jm-vmodal__head h2 { margin: 0; font-size: 1.02rem; font-weight: 700; flex: 1; }
/* Count of lessons in the playlist, set by course-landing.js. */
.jm-vmodal__count { display: block; margin-top: 3px; font-size: .78rem; font-weight: 400; color: var(--faint); }
.jm-vmodal__list { flex: 1; overflow-y: auto; padding: 10px; display: grid; gap: 6px; align-content: start; }

.jm-vpl-item {
    display: flex; align-items: center; gap: 13px; width: 100%; padding: 11px 12px;
    border-radius: 12px; background: none; border: 1px solid transparent; cursor: pointer;
    color: var(--text); text-align: start; font-family: inherit;
    transition: background .16s, border-color .16s, transform .16s;
}
.jm-vpl-item:hover { background: var(--card2); border-color: var(--border); }
.jm-vpl-item:active { transform: scale(.995); }
/* Active item: an accent bar plus the tint, so the current lesson is obvious at a glance. */
.jm-vpl-item.video-playlist-item-active {
    background: rgba(249, 161, 27, .13); border-color: var(--border2);
    position: relative;
}
.jm-vpl-item.video-playlist-item-active::before {
    content: ""; position: absolute; inset-block: 10px; inset-inline-start: 0; width: 3px;
    border-radius: 0 3px 3px 0; background: var(--grad);
}
[dir="rtl"] .jm-vpl-item.video-playlist-item-active::before { border-radius: 3px 0 0 3px; }
.jm-vpl-item__thumb {
    width: 62px; height: 40px; border-radius: 8px; overflow: hidden; background: var(--thumb-bg);
    display: grid; place-items: center; flex: none; color: var(--faint);
}
.jm-vpl-item__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.jm-vpl-item__thumb svg { width: 18px; height: 18px; }
.jm-vpl-item__body { min-width: 0; flex: 1; }
.jm-vpl-item__title { display: block; font-size: .89rem; font-weight: 600; line-height: 1.45; }
.jm-vpl-item__sub { display: block; margin-top: 2px; font-size: .76rem; color: var(--faint); }

/* Below md the player stacks on top and the playlist becomes a scrollable strip under it. */
@media (max-width: 1023px) {
    .jm-modal-panel--video { width: 96vw; max-width: 96vw; border-radius: 14px; }
    .jm-vmodal { grid-template-columns: 1fr; }
    .jm-vmodal__side { max-height: 38vh; border-inline-start: 0; border-top: 1px solid var(--border); }
    .jm-vmodal__head { padding: 14px 16px 12px; padding-inline-end: 56px; }
}

/* subscription plan modals */
.jm-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; align-items: start; }
.jm-plan { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--r); background: var(--card); overflow: hidden; }
.jm-plan--popular { border-color: var(--border2); box-shadow: var(--glow); }
.jm-plan__strip { background: var(--grad); color: var(--btn-text); font-size: .75rem; font-weight: 700; padding: 5px 10px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.jm-plan__strip svg { width: 14px; height: 14px; }
.jm-plan__head { padding: 18px 20px; border-bottom: 1px solid var(--border); }
.jm-plan__head h3 { margin: 0; font-size: 1.05rem; line-height: 1.4; }
.jm-plan__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.jm-plan__price { display: flex; align-items: baseline; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.jm-plan__body { padding: 18px 20px; flex: 1; }
.jm-plan__body ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-size: .9rem; color: var(--muted); }
.jm-plan__body li { display: flex; gap: 8px; align-items: flex-start; }
.jm-plan__body li svg { width: 16px; height: 16px; color: var(--success); flex: none; margin-top: 4px; }
.jm-plan__foot { padding: 0 20px 20px; }

/* points redemption modal + pay-with-points box */
.jm-points-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.jm-points-head .jm-ficon { margin: 0; width: 44px; height: 44px; border-radius: 12px; flex: none; }
.jm-points-head .jm-ficon svg { width: 22px; height: 22px; }
.jm-points-head h3 { margin: 0; font-size: 1.1rem; }
.jm-points-body p { margin: 0 0 10px; color: var(--muted); font-size: .95rem; line-height: 1.7; }
.jm-points-body b { color: var(--text); font-variant-numeric: tabular-nums; }
.jm-points-body .jm-points-val { color: var(--accent-ink); }
.jm-points-body .jm-points-rem { color: var(--success); }
.jm-points-pay { margin-top: 12px; }
.jm-points-pay__meta { min-width: 0; flex: 1; }
.jm-points-pay__eyebrow { margin: 0; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-ink); }
.jm-points-pay__cost { margin: 0; font-size: .92rem; color: var(--muted); }
.jm-points-pay__cost b { color: var(--text); font-variant-numeric: tabular-nums; }
.jm-points-pay__cost small { font-size: .8rem; color: var(--faint); }

/* enrollment success */
.jm-status--enroll { position: relative; max-width: 620px; }
.jm-status__course { text-align: start; margin-top: 28px; background: var(--bg2); }
.jm-status__course:hover { transform: none; }
.jm-status__course .jm-cbody h2 { margin: 0; font-size: 1.1rem; line-height: 1.5; }

/* ratings (rv-* / rva-* markup from public-pages.css) — token overrides so the
   section follows the light/dark theme instead of its own warm palette */
body.jm-site .rv-section, body.jm-site .rva-section { background: var(--card); border-color: var(--border); scroll-margin-top: calc(90px + var(--ann-bar-h, 0px)); }
body.jm-site .rv-heading, body.jm-site .rv-score-num, body.jm-site .rv-card__name,
body.jm-site .rva-heading, body.jm-site .rva-item__name { color: var(--text); }
body.jm-site .rv-heading::after { background: linear-gradient(to right, var(--border2), transparent); }
[dir="rtl"] body.jm-site .rv-heading::after { background: linear-gradient(to left, var(--border2), transparent); }
body.jm-site .rv-summary, body.jm-site .rva-item, body.jm-site .rva-skeleton { border-color: var(--border); }
body.jm-site .rv-score-out, body.jm-site .rv-bar-label, body.jm-site .rv-card__text, body.jm-site .rva-item__text { color: var(--muted); }
body.jm-site .rv-score-count, body.jm-site .rv-bar-count, body.jm-site .rv-sub-heading, body.jm-site .rva-item__date,
body.jm-site .rv-card__text--empty, body.jm-site .rva-item__text--empty, body.jm-site .rva-all-done { color: var(--faint); }
body.jm-site .rv-bar-track { background: var(--card2); }
body.jm-site .rv-bar-fill, body.jm-site .rv-card__avatar, body.jm-site .rva-item__avatar, body.jm-site .rva-item__accent { background: var(--grad); }
body.jm-site .rv-card__avatar, body.jm-site .rva-item__avatar { color: var(--btn-text); }
body.jm-site .rv-sum-stars--empty, body.jm-site .rv-star-empty, body.jm-site .rva-star-empty { color: var(--border); }
body.jm-site .rv-sum-stars--filled, body.jm-site .rv-star-filled, body.jm-site .rva-star-filled, body.jm-site .rv-bar-label svg { color: var(--accent2); }
body.jm-site .rv-card { background: var(--bg2); border-color: var(--border); }
body.jm-site .rv-card__quote { color: var(--border2); }
body.jm-site .rv-view-all-link, body.jm-site .rva-count-badge { color: var(--accent-ink); }
body.jm-site .rva-count-badge { background: rgba(249, 161, 27, .12); }
body.jm-site .rva-load-btn { color: var(--accent-ink); border-color: var(--border2); }
body.jm-site .rva-load-btn:hover { border-color: var(--accent); }
body.jm-site .rva-item__badge { background: var(--success-soft); color: var(--success); }
body.jm-site .rva-skel-avatar, body.jm-site .rva-skel-line { background: linear-gradient(90deg, var(--card) 25%, var(--card2) 50%, var(--card) 75%); background-size: 200% 100%; }
body.jm-site .rva-all-done::before, body.jm-site .rva-all-done::after { background: var(--border); }
.rva-item__meta { flex: 1; min-width: 0; }
.rva-item__stars-row { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.rva-load-btn[hidden], .rva-all-done[hidden] { display: none !important; }

/* ---------- auth / status / invoice pages ---------- */
/* .jm-code-float is direction:ltr, so inset-inline-* resolve to left/right regardless of page dir */
.jm-code-float--auth1 { top: 7%; inset-inline-end: 7%; }
.jm-code-float--auth2 { bottom: 9%; inset-inline-end: 8%; }
.jm-code-float--auth3 { top: 19%; inset-inline-start: 6%; }
.jm-auth-brand .jm-logo img { height: 52px; }
.jm-auth-card--wide { max-width: 560px; }
.jm-auth-icon { width: 64px; height: 64px; margin: 0 0 18px; }
.jm-auth-icon svg { width: 30px; height: 30px; }
.jm-auth-card.jm-center .jm-status-icon { margin-inline: auto; }
.jm-auth-card.jm-center > p { margin-bottom: 22px; }
.jm-auth-card form + .jm-auth-foot, .jm-auth-card .jm-btn + .jm-auth-foot { margin-top: 22px; }
.jm-auth-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 0 0 18px; }
.jm-auth-facts > div { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 14px 10px; text-align: center; }
.jm-auth-facts dd { margin: 0; font-size: 1.35rem; font-weight: 700; line-height: 1.2; background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; font-variant-numeric: tabular-nums; }
.jm-auth-facts dt { color: var(--faint); font-size: .74rem; font-weight: 600; margin-top: 4px; }
@media (max-width: 480px) { .jm-auth-facts { grid-template-columns: 1fr; } }
.jm-input-wrap:has(> button) > .jm-input { padding-inline-end: 44px; }
.jm-input-wrap > button[aria-pressed="true"] { color: var(--accent-ink); }
/* Tailwind's .hidden must beat the component display rules (site.css loads later) */
.jm-alert.hidden, .jm-modal.hidden { display: none; }
.jm-link-btn { background: none; border: 0; padding: 0; color: var(--accent-ink); font-weight: 700; font-size: .9rem; cursor: pointer; font-family: inherit; }
.jm-link-btn:hover { text-decoration: underline; }
.jm-link-btn--danger { color: var(--faint); font-weight: 600; font-size: .82rem; }
.jm-link-btn--danger:hover { color: var(--danger); }
.jm-spinner { display: inline-block; width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--accent); animation: jm-spin .8s linear infinite; }
@keyframes jm-spin { to { transform: rotate(360deg); } }
.jm-step { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--grad); color: var(--btn-text); font-size: .85rem; font-weight: 700; flex: none; }
.jm-invoice { max-width: 820px; margin-inline: auto; display: grid; gap: 18px; }
.jm-invoice-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.jm-invoice-head__main { display: grid; gap: 10px; justify-items: start; }
.jm-invoice-number { font-size: clamp(1.3rem, 3vw, 1.8rem); margin: 0; letter-spacing: -.3px; }
.jm-invoice-head .jm-price-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.jm-invoice-qr { flex-direction: column; align-items: center; gap: 6px; margin: 0; }
.jm-invoice-qr img { width: 120px; height: 120px; border-radius: 12px; background: #fff; padding: 6px; border: 1px solid var(--border); }
.jm-invoice-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin: 0; }
.jm-invoice-meta dt { color: var(--faint); font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px; }
.jm-invoice-meta dd { margin: 0; color: var(--text); font-weight: 600; font-size: .95rem; }
.jm-invoice-summary { margin: 14px 0 0; padding: 14px 14px 0; border-top: 1px solid var(--border); display: grid; gap: 8px; }
.jm-invoice-summary > div { display: flex; justify-content: space-between; gap: 16px; color: var(--muted); font-size: .92rem; }
.jm-invoice-summary dd { margin: 0; }
.jm-invoice-summary__discount { color: var(--danger); }
.jm-invoice-summary > .jm-invoice-summary__total { color: var(--text); font-weight: 700; font-size: 1.05rem; padding-top: 10px; border-top: 1px dashed var(--border); }
.jm-invoice-auth-links { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 0; padding-top: 14px; border-top: 1px solid var(--border); }
.jm-invoice-secure { display: flex; align-items: center; justify-content: center; gap: 8px; color: var(--faint); font-size: .82rem; margin: 22px 0 0; }
.jm-invoice-secure svg { width: 14px; height: 14px; flex: none; }
.jm-invoice .jm-pane .jm-form-row { margin-bottom: 0; }
/* Legacy `.dark main input[type=…]` rules in public-pages.css out-specify .jm-input; re-assert the tokens. */
html.dark body.jm-site main :is(.jm-input, .jm-select, .jm-textarea) { background: var(--bg2); border-color: var(--border); color: var(--text); }
html.dark body.jm-site main :is(.jm-input, .jm-select, .jm-textarea):focus { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(249, 161, 27, .18); }
html.dark body.jm-site main :is(.jm-input, .jm-select, .jm-textarea).is-invalid { border-color: var(--danger); box-shadow: 0 0 0 4px var(--danger-soft); }
body.jm-site :is(.jm-input, .jm-select, .jm-textarea):focus-visible { outline: none; }
/* reCAPTCHA (and similar) append wrapper divs to <body>; keep them out of the split grid's row space. */
.jm-auth { grid-template-rows: 1fr; grid-auto-rows: 0; }
.jm-auth > .jm-auth-brand, .jm-auth > .jm-auth-main { grid-row: 1; }
/* visually-hidden native select behind the searchable combobox must not take .jm-select width */
.jm-select.dsc-native-hidden { width: 1px; height: 1px; padding: 0; border: 0; }
.jm-price.jm-gtext { color: transparent; }

/* ---------- Home: welcome back + resume learning (signed-in students) ---------- */
.jm-welcome { position: relative; padding: 44px 0 40px; border-bottom: 1px solid var(--border); }
.jm-welcome-head { display: flex; align-items: center; gap: 20px; margin-bottom: 38px; }
.jm-welcome-avatar { flex: none; }
.jm-welcome-title { margin: 0 0 6px; font-size: clamp(1.3rem, 2.6vw, 1.7rem); font-weight: 700; line-height: 1.35; color: var(--text); letter-spacing: -.2px; }
.jm-welcome-meta { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; color: var(--muted); }
.jm-welcome-link { color: var(--accent-ink); font-weight: 700; text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.jm-welcome-link:hover { color: var(--text); }
.jm-welcome-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.jm-learn-row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.jm-learn-row h2 { margin: 0; font-size: clamp(1.45rem, 3vw, 2rem); font-weight: 700; line-height: 1.3; letter-spacing: -.3px; }
.jm-resume { position: relative; }
.jm-resume-track { list-style: none; margin: 0; padding: 4px 2px 10px; display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 36px) / 3); gap: 18px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.jm-resume-track::-webkit-scrollbar { display: none; }
@media (max-width: 980px) { .jm-resume-track { grid-auto-columns: calc((100% - 18px) / 2); } }
@media (max-width: 640px) { .jm-resume-track { grid-auto-columns: 86%; } }
.jm-resume-item { scroll-snap-align: start; min-width: 0; }
.jm-resume-card { display: grid; grid-template-columns: 38% 1fr; height: 100%; min-height: 156px; background: var(--bg2); border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden; color: var(--text); transition: border-color .18s; }
.jm-resume-card:hover { border-color: var(--border2); color: var(--text); }
.jm-resume-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.jm-resume-thumb { position: relative; background: var(--thumb-bg); overflow: hidden; }
.jm-resume-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.jm-resume-thumb::after { content: ""; position: absolute; inset: 0; background: rgba(7, 11, 23, .3); transition: background .18s; }
.jm-resume-card:hover .jm-resume-thumb::after { background: rgba(7, 11, 23, .12); }
.jm-resume-play { position: absolute; z-index: 1; inset: 0; margin: auto; width: 50px; height: 50px; border-radius: 50%; background: #ffffff; color: #070b17; display: grid; place-items: center; box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .5); transition: transform .18s, background .18s; }
.jm-resume-play svg { width: 18px; height: 18px; margin-inline-start: 3px; }
[dir="rtl"] .jm-resume-play svg { margin-inline-start: 0; margin-inline-end: -3px; }
.jm-resume-card:hover .jm-resume-play { transform: scale(1.08); background: var(--accent); }
.jm-resume-bar { position: absolute; z-index: 1; inset-inline: 0; bottom: 0; display: block; width: 100%; height: 4px; border: 0; appearance: none; -webkit-appearance: none; background: rgba(255, 255, 255, .3); }
.jm-resume-bar::-webkit-progress-bar { background: rgba(255, 255, 255, .3); }
.jm-resume-bar::-webkit-progress-value { background: var(--accent); }
.jm-resume-bar::-moz-progress-bar { background: var(--accent); }
.jm-resume-body { display: flex; flex-direction: column; gap: 6px; padding: 16px 18px; min-width: 0; }
.jm-resume-course { color: var(--faint); font-size: .8rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jm-resume-lecture { font-weight: 700; font-size: 1rem; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.jm-resume-meta { margin-top: auto; padding-top: 8px; display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: .82rem; }
.jm-resume-type { font-weight: 700; }
.jm-resume-meta > * + *::before { content: ""; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: currentColor; vertical-align: middle; margin-inline-end: 8px; }
.jm-resume-nav { position: absolute; z-index: 2; top: 50%; width: 44px; height: 44px; margin-top: -27px; border-radius: 50%; border: 1px solid var(--border); background: var(--bg2); color: var(--text); display: grid; place-items: center; box-shadow: var(--shadow); cursor: pointer; }
.jm-resume-nav[hidden] { display: none; }
.jm-resume-nav:hover { border-color: var(--border2); color: var(--accent-ink); }
.jm-resume-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.jm-resume-nav svg { width: 20px; height: 20px; }
.jm-resume-nav--prev { inset-inline-start: -14px; }
.jm-resume-nav--next { inset-inline-end: -14px; }
.jm-resume-empty { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 22px 24px; border: 1px dashed var(--border); border-radius: var(--r-sm); background: var(--card); }
.jm-resume-empty p { margin: 0; color: var(--muted); }
@media (max-width: 640px) { .jm-resume-nav { display: none; } .jm-welcome { padding: 32px 0; } .jm-welcome-head { gap: 14px; margin-bottom: 28px; } }
@media (max-width: 480px) { .jm-resume-card { grid-template-columns: 1fr; } .jm-resume-thumb { aspect-ratio: 16 / 9; } }
@media (prefers-reduced-motion: reduce) { .jm-resume-card, .jm-resume-play, .jm-resume-thumb::after { transition: none; } .jm-resume-card:hover .jm-resume-play { transform: none; } }

/* ---------- Course landing: one grid for hero + body; the preview video lives in the purchase card ---------- */
.jm-cpage { position: relative; overflow-x: clip; }
.jm-cdetail.jm-cpage__grid {
    grid-template-columns: minmax(0, 1fr) 360px;
    grid-template-areas: "hero side" "main side";
    grid-template-rows: auto 1fr;
    column-gap: 44px; row-gap: 0;
    align-items: start;
}
.jm-cpage__hero { grid-area: hero; position: relative; padding: 42px 0 46px; }
.jm-cpage__hero > .jm-hero-bg { inset: 0 -100vw; z-index: 0; }
.jm-cpage__hero > :not(.jm-hero-bg) { position: relative; z-index: 1; }
.jm-cpage__hero .jm-meta-row { margin-bottom: 24px; }
.jm-cpage__side { grid-area: side; position: relative; z-index: 2; align-self: stretch; padding: 42px 0 64px; }
.jm-cpage__main { grid-area: main; padding: 44px 0 64px; }

.jm-cpage .jm-pricing { padding: 0; gap: 0; box-shadow: var(--shadow); }
.jm-pricing__body { display: grid; gap: 14px; padding: 22px 22px 24px; }
.jm-cpreview { border-bottom: 1px solid var(--border); }
.jm-cpreview__frame { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #04060c; border-start-start-radius: calc(var(--r) - 1px); border-start-end-radius: calc(var(--r) - 1px); }
.jm-cpreview__frame img, .jm-cpreview__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border: 0; display: block; }
.jm-cpreview__ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--faint); background: linear-gradient(135deg, var(--card2), var(--thumb-bg)); }
.jm-cpreview__ph svg { width: 48px; height: 48px; }
.jm-cpreview__play { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 12px; padding: 16px; border: 0; cursor: pointer; color: #ffffff; font: inherit; background: linear-gradient(180deg, rgba(4, 6, 12, .12), rgba(4, 6, 12, .62)); transition: background .2s; }
.jm-cpreview__play:hover { background: linear-gradient(180deg, rgba(4, 6, 12, .04), rgba(4, 6, 12, .5)); }
.jm-cpreview__play:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.jm-cpreview__playicon { width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center; background: var(--grad); color: var(--btn-text); box-shadow: var(--glow); transition: transform .18s; }
.jm-cpreview__play:hover .jm-cpreview__playicon { transform: scale(1.06); }
.jm-cpreview__playicon svg { width: 26px; height: 26px; margin-left: 3px; }
.jm-cpreview__label { font-size: .95rem; font-weight: 700; text-shadow: 0 1px 10px rgba(0, 0, 0, .55); }
.jm-cpreview__more { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 11px 14px; border: 0; background: var(--card); color: var(--accent-ink); font: inherit; font-size: .88rem; font-weight: 700; cursor: pointer; }
.jm-cpreview__more:hover { background: var(--card2); }
.jm-cpreview__more svg { width: 17px; height: 17px; flex: none; }

@media (max-width: 1023px) {
    .jm-cdetail.jm-cpage__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "hero" "side" "main"; grid-template-rows: auto; }
    .jm-cpage__hero { padding: 24px 0 26px; }
    .jm-cpage__side { padding: 0; align-self: start; }
    .jm-cpage .jm-pricing { overflow: hidden; max-width: 560px; }
    .jm-cpage__main { padding: 36px 0 48px; }
}
@media (prefers-reduced-motion: reduce) { .jm-cpreview__play, .jm-cpreview__playicon { transition: none; } }

/* Narrow phones: nothing may be wider than the screen */
@media (max-width: 1023px) { .jm-cdetail { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 560px) {
    .jm-curr__head { flex-wrap: wrap; }
    .jm-curr__head small { white-space: normal; }
    .jm-curr__item { flex-wrap: wrap; }
    .jm-curr__end { flex-wrap: wrap; justify-content: flex-end; }
}
@media (max-width: 380px) {
    .jm-wrap { padding-inline: 16px; }
    .jm-hdr-in { gap: 8px; }
    .jm-tools { gap: 6px; }
    .jm-lang a { padding: 3px 7px; }
    body.jm-site .jm-logo img { height: 32px; }
}
/* Title/summary keep dir="auto" for correct bidi, but align with the page so an English title
   on the Arabic page doesn't jump to the opposite edge from the breadcrumb and chips. */
html[dir="rtl"] .jm-cpage__hero :is(h1, .jm-lead) { text-align: right; }
html[dir="ltr"] .jm-cpage__hero :is(h1, .jm-lead) { text-align: left; }

/* ---------- Home (signed-in): welcome header polish + subscribe nudge ----------
   Signed-in visitors skip the marketing hero; the welcome block owns the page H1
   and sits directly under the site header. The nudge is an "all-access pass":
   a ticket card whose stub (price + CTA) is split off by a perforated edge. */
.jm-welcome { position: relative; overflow: hidden; border-bottom: 0; padding-top: 52px; }
.jm-welcome > .jm-wrap { position: relative; }
.jm-welcome-bg::before { -webkit-mask-image: radial-gradient(46rem 22rem at 50% 0, #000 20%, transparent 72%); mask-image: radial-gradient(46rem 22rem at 50% 0, #000 20%, transparent 72%); }
h1.jm-welcome-title { font-size: clamp(1.6rem, 3.8vw, 2.35rem); line-height: 1.25; letter-spacing: -.4px; margin: 0 0 8px; }

.jm-subnudge-sec { padding: 8px 0 0; }
.jm-subnudge-sec[hidden] { display: none; }
.jm-subnudge {
    position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    border: 1px solid var(--border2); border-radius: 22px; overflow: hidden; background: var(--bg2); box-shadow: var(--shadow);
    transition: opacity .22s ease, transform .22s ease;
}
.jm-subnudge.is-leaving { opacity: 0; transform: translateY(-6px) scale(.99); }
.jm-subnudge-main { padding: 34px 36px; min-width: 0; }
.jm-subnudge-icon {
    display: inline-grid; place-items: center; width: 46px; height: 46px; border-radius: 13px; margin-bottom: 18px;
    color: var(--accent-ink); background: rgba(249, 161, 27, .12); border: 1px solid rgba(249, 161, 27, .3);
}
.jm-subnudge-icon svg { width: 24px; height: 24px; }
[dir="rtl"] .jm-subnudge-icon svg { transform: scaleX(-1); }
.jm-subnudge-main h2 { margin: 0 0 10px; font-size: clamp(1.3rem, 2.6vw, 1.7rem); line-height: 1.35; letter-spacing: -.2px; max-width: 30ch; }
.jm-subnudge-lead { margin: 0 0 22px; color: var(--muted); max-width: 52ch; }
.jm-subnudge-perks { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.jm-subnudge-perks li { display: flex; align-items: flex-start; gap: 11px; color: var(--text); font-weight: 600; font-size: .95rem; line-height: 1.5; }
.jm-subnudge-perks svg { flex: none; width: 20px; height: 20px; margin-top: 1px; padding: 3px; border-radius: 50%; color: var(--success); background: var(--success-soft); }

/* Ticket stub: perforated edge + half-circle notches cut out of the card border */
.jm-subnudge-pass {
    position: relative; display: flex; flex-direction: column; gap: 10px; justify-content: center; padding: 30px 28px;
    border-inline-start: 2px dashed var(--border2);
    background: linear-gradient(165deg, rgba(249, 161, 27, .16), rgba(249, 161, 27, .03) 70%);
}
.jm-subnudge-pass::before, .jm-subnudge-pass::after {
    content: ""; position: absolute; inset-inline-start: -13px; width: 24px; height: 24px; border-radius: 50%;
    background: var(--bg); border: 1px solid var(--border2);
}
.jm-subnudge-pass::before { top: -13px; }
.jm-subnudge-pass::after { bottom: -13px; }
.jm-subnudge-badge { align-self: flex-start; font-size: .74rem; padding: 3px 11px; }
.jm-subnudge-plan { margin: 0; font-size: 1.12rem; line-height: 1.4; color: var(--text); }
/* dir="auto" keeps an English plan name's bidi correct; align it with the page like the course hero does */
html[dir="rtl"] .jm-subnudge-plan { text-align: right; }
html[dir="ltr"] .jm-subnudge-plan { text-align: left; }
.jm-subnudge-price { margin: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.jm-subnudge-price .jm-price--lg { font-size: 2.2rem; line-height: 1.1; letter-spacing: -.5px; }
.jm-subnudge-period { color: var(--faint); font-size: .9rem; font-weight: 600; }
.jm-subnudge-period::before { content: "/ "; }
.jm-subnudge-scope { margin: 0 0 8px; display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: .9rem; }
.jm-subnudge-scope svg { flex: none; width: 17px; height: 17px; color: var(--accent-ink); }
.jm-subnudge-dismiss {
    align-self: center; margin-top: 2px; padding: 6px 12px; border: 0; border-radius: 8px; background: transparent;
    color: var(--muted); font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer;
}
.jm-subnudge-dismiss:hover { color: var(--text); background: var(--card2); }
.jm-subnudge-dismiss:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 760px) {
    .jm-subnudge { grid-template-columns: minmax(0, 1fr); border-radius: 18px; }
    .jm-subnudge-main { padding: 26px 22px 24px; }
    .jm-subnudge-pass { padding: 26px 22px 20px; border-inline-start: 0; border-top: 2px dashed var(--border2); }
    .jm-subnudge-pass::before, .jm-subnudge-pass::after { top: -13px; bottom: auto; }
    .jm-subnudge-pass::before { inset-inline-start: -13px; }
    .jm-subnudge-pass::after { inset-inline-start: auto; inset-inline-end: -13px; }
    .jm-subnudge-main h2 { max-width: none; }
}
@media (max-width: 640px) { .jm-welcome { padding-top: 36px; } }
@media (prefers-reduced-motion: reduce) { .jm-subnudge { transition: none; } .jm-subnudge.is-leaving { transform: none; } }

/* ============================================================
   Avatar + tier crest (fragments/avatar.html)
   ------------------------------------------------------------
   Lives here, not in dashboard.css, because the public pages
   (home, catalog, blog, community, reviews) render the same
   fragment. The tier classes are built by Thymeleaf from the
   badge name ('avatar--tier-' + tier), so none of them may be
   removed as "unused".
   ============================================================ */
/* ============================================================
   Avatar + Tier Crest — premium achievement indicator
   Metallic crests tucked into bottom-end corner of the avatar.
   Tiers: GOLD_CUP > SILVER_CUP > GOLD_MEDAL > SILVER_MEDAL
          > GOLDEN_EAGLE > SILVER_EAGLE > COURSE_COMPLETE
   ============================================================ */

.avatar {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    line-height: 0;
}

.avatar__frame {
    display: inline-flex;
    width: 100%;
    height: 100%;
    border-radius: 9999px;
    overflow: hidden;
    background: linear-gradient(135deg, #4f46e5, #7c3aed);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}

.avatar__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar__initial {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    color: #ffffff;
    background: linear-gradient(135deg, #4f46e5, #7c3aed);
}

/* Size variants */
.avatar--xs { width: 1.5rem;   height: 1.5rem;   }
.avatar--sm { width: 1.875rem; height: 1.875rem; }
.avatar--md { width: 2.75rem;  height: 2.75rem;  }
.avatar--lg { width: 4rem;     height: 4rem;     }
.avatar--xl { width: 7rem;     height: 7rem;     }

.avatar--xs .avatar__initial { font-size: 0.625rem; }
.avatar--sm .avatar__initial { font-size: 0.75rem;  }
.avatar--md .avatar__initial { font-size: 0.9375rem;}
.avatar--lg .avatar__initial { font-size: 1.375rem; }
.avatar--xl .avatar__initial { font-size: 2.25rem;  }

/* When a crest is present, tighten the frame with a refined ring
   that hints at the tier without overwhelming the portrait. */
.avatar--has-crest .avatar__frame {
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.4),
        0 0 0 2px var(--crest-ring, rgba(99, 102, 241, 0.35)),
        0 4px 10px -2px var(--crest-glow, rgba(99, 102, 241, 0.25));
}

/* Tier color variables — used by ring + crest */
.avatar--tier-gold_cup      { --crest-fg: #f59e0b; --crest-bg: linear-gradient(140deg, #fde68a 0%, #f59e0b 48%, #b45309 100%); --crest-ring: rgba(245, 158, 11, 0.55); --crest-glow: rgba(245, 158, 11, 0.35); }
.avatar--tier-silver_cup    { --crest-fg: #64748b; --crest-bg: linear-gradient(140deg, #f1f5f9 0%, #cbd5e1 48%, #64748b 100%); --crest-ring: rgba(100, 116, 139, 0.50); --crest-glow: rgba(100, 116, 139, 0.28); }
.avatar--tier-gold_medal    { --crest-fg: #ca8a04; --crest-bg: linear-gradient(140deg, #fef3c7 0%, #facc15 45%, #a16207 100%); --crest-ring: rgba(234, 179, 8, 0.50); --crest-glow: rgba(234, 179, 8, 0.30); }
.avatar--tier-silver_medal  { --crest-fg: #475569; --crest-bg: linear-gradient(140deg, #f8fafc 0%, #cbd5e1 48%, #475569 100%); --crest-ring: rgba(100, 116, 139, 0.45); --crest-glow: rgba(100, 116, 139, 0.24); }
.avatar--tier-golden_eagle  { --crest-fg: #b45309; --crest-bg: linear-gradient(140deg, #fcd34d 0%, #d97706 55%, #78350f 100%); --crest-ring: rgba(217, 119, 6, 0.50); --crest-glow: rgba(217, 119, 6, 0.30); }
.avatar--tier-silver_eagle  { --crest-fg: #475569; --crest-bg: linear-gradient(140deg, #e2e8f0 0%, #94a3b8 55%, #334155 100%); --crest-ring: rgba(100, 116, 139, 0.45); --crest-glow: rgba(100, 116, 139, 0.22); }
.avatar--tier-course_complete { --crest-fg: #059669; --crest-bg: linear-gradient(140deg, #a7f3d0 0%, #10b981 55%, #065f46 100%); --crest-ring: rgba(16, 185, 129, 0.45); --crest-glow: rgba(16, 185, 129, 0.22); }

/* The crest chip */
.avatar__crest {
    position: absolute;
    inset-inline-end: -6%;
    inset-block-end: -6%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--crest-bg);
    color: #ffffff;
    border-radius: 9999px;
    box-shadow:
        0 0 0 2px #ffffff,
        0 2px 6px rgba(15, 23, 42, 0.25),
        inset 0 1px 0 rgba(255, 255, 255, 0.55),
        inset 0 -1px 0 rgba(0, 0, 0, 0.18);
    transform: translateZ(0);
}

.avatar__crest-icon {
    display: block;
    width: 62%;
    height: 62%;
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.35));
}

/* Crest sizing per avatar size */
.avatar--xs .avatar__crest { width: 0.75rem;  height: 0.75rem;  box-shadow: 0 0 0 1.5px #ffffff, 0 1px 3px rgba(15,23,42,0.25); }
.avatar--sm .avatar__crest { width: 0.95rem;  height: 0.95rem;  }
.avatar--md .avatar__crest { width: 1.2rem;   height: 1.2rem;   }
.avatar--lg .avatar__crest { width: 1.6rem;   height: 1.6rem;   }
.avatar--xl .avatar__crest { width: 2.4rem;   height: 2.4rem;   }

/* Subtle shine animation on the top tier only */
.avatar--tier-gold_cup .avatar__crest::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(120deg, transparent 35%, rgba(255,255,255,0.55) 50%, transparent 65%);
    background-size: 220% 100%;
    animation: avatar-crest-shine 3.2s ease-in-out infinite;
    pointer-events: none;
}
@keyframes avatar-crest-shine {
    0%   { background-position: 120% 0; }
    60%  { background-position: -20% 0; }
    100% { background-position: -20% 0; }
}

/* Dark-mode tweaks — lift the crest against dark backgrounds */
.dark .avatar__crest {
    box-shadow:
        0 0 0 2px #161927,
        0 2px 8px rgba(0, 0, 0, 0.55),
        inset 0 1px 0 rgba(255, 255, 255, 0.45),
        inset 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.dark .avatar--has-crest .avatar__frame {
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.2),
        0 0 0 2px var(--crest-ring, rgba(99, 102, 241, 0.35)),
        0 4px 14px -2px var(--crest-glow, rgba(99, 102, 241, 0.35));
}
.dark .avatar--xs .avatar__crest {
    box-shadow: 0 0 0 1.5px #161927, 0 1px 3px rgba(0,0,0,0.55);
}

/* Profile page — larger crest + premium ring around the 112px portrait */
.profile-avatar { display: inline-block; }
.profile-avatar--has-crest {
    padding: 2px;
    border-radius: 9999px;
    background: var(--crest-bg, linear-gradient(135deg, #4f46e5, #7c3aed));
    box-shadow: 0 10px 30px -12px var(--crest-glow, rgba(79, 70, 229, 0.35));
}
.profile-avatar--has-crest > div:first-child img,
.profile-avatar--has-crest > div:first-child > div {
    border-color: #ffffff !important;
}
.profile-avatar__crest {
    width: 2.25rem;
    height: 2.25rem;
    inset-inline-end: 2px;
    inset-block-end: 2px;
}
.dark .profile-avatar--has-crest > div:first-child img,
.dark .profile-avatar--has-crest > div:first-child > div {
    border-color: #0f1220 !important;
}
.profile-avatar__tier-caption {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: 0.25rem;
    margin-bottom: 0.75rem;
    padding: 0.2rem 0.75rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #78350f;
    background: linear-gradient(135deg, rgba(253, 230, 138, 0.6), rgba(245, 158, 11, 0.12));
    border: 1px solid rgba(245, 158, 11, 0.35);
    border-radius: 9999px;
}
.dark .profile-avatar__tier-caption {
    color: #fde68a;
    background: linear-gradient(135deg, rgba(120, 53, 15, 0.35), rgba(217, 119, 6, 0.12));
    border-color: rgba(217, 119, 6, 0.4);
}

/* ============================================================
   Rewards Strip — dashboard "My Rewards" card
   ============================================================ */

.rewards-strip {
    position: relative;
    background: #ffffff;
    border: 1px solid rgba(226, 232, 240, 0.9);
    border-radius: 1rem;
    padding: 1.25rem 1.25rem 1.5rem;
    margin-bottom: 2rem;
    box-shadow: 0 4px 14px -6px rgba(15, 23, 42, 0.06);
    overflow: hidden;
}
.rewards-strip::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 60% 50% at 100% 0%, rgba(245, 158, 11, 0.10), transparent 70%),
        radial-gradient(ellipse 50% 60% at 0% 100%, rgba(99, 102, 241, 0.06), transparent 70%);
    pointer-events: none;
}
.rewards-strip > * { position: relative; }

.rewards-strip__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 0.875rem;
}
.rewards-strip__head-left {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.rewards-strip__ornament {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.75rem;
    background: linear-gradient(140deg, #fde68a 0%, #f59e0b 60%, #b45309 100%);
    color: #ffffff;
    box-shadow: 0 4px 10px -3px rgba(245, 158, 11, 0.45);
}
.rewards-strip__ornament svg { width: 1.1rem; height: 1.1rem; }
.rewards-strip__title {
    font-size: 1rem;
    font-weight: 700;
    color: #0f172a;
    line-height: 1.2;
}
.rewards-strip__subtitle {
    font-size: 0.8125rem;
    color: #64748b;
    margin-top: 0.15rem;
}
.rewards-strip__link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: #4f46e5;
    padding: 0.3rem 0.6rem;
    border-radius: 0.5rem;
    transition: background 0.15s ease;
}
.rewards-strip__link:hover { background: rgba(99, 102, 241, 0.08); }
.rewards-strip__link svg { width: 0.75rem; height: 0.75rem; }

.rewards-strip__progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.125rem;
}
.rewards-strip__progress-track {
    flex: 1;
    height: 6px;
    background: rgba(148, 163, 184, 0.18);
    border-radius: 9999px;
    overflow: hidden;
}
.rewards-strip__progress-fill {
    height: 100%;
    background: linear-gradient(90deg, #f59e0b, #ec4899, #8b5cf6);
    border-radius: inherit;
    transition: width 0.6s ease;
}
.rewards-strip__progress-count {
    font-size: 0.75rem;
    font-weight: 700;
    color: #64748b;
    font-variant-numeric: tabular-nums;
    min-width: 2.5rem;
    text-align: end;
}

.rewards-strip__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.625rem;
}
@media (min-width: 640px) {
    .rewards-strip__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
    .rewards-strip__grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
}

/* Individual tile */
.rewards-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.5rem;
    padding: 0.875rem 0.625rem;
    border-radius: 0.875rem;
    background: #f8fafc;
    border: 1px solid rgba(226, 232, 240, 0.8);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.rewards-tile:hover { transform: translateY(-2px); box-shadow: 0 8px 22px -10px rgba(15, 23, 42, 0.18); }

.rewards-tile--earned {
    background: linear-gradient(160deg, #ffffff 0%, #fef9e7 100%);
    border-color: rgba(245, 158, 11, 0.28);
}
.rewards-tile--locked {
    background: repeating-linear-gradient(135deg, #f8fafc 0 8px, #f1f5f9 8px 16px);
    opacity: 0.86;
}

.rewards-tile__medallion {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 9999px;
    color: #ffffff;
    background: var(--crest-bg, linear-gradient(140deg, #cbd5e1 0%, #94a3b8 60%, #475569 100%));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.45),
        inset 0 -2px 0 rgba(0, 0, 0, 0.15),
        0 6px 14px -6px var(--crest-glow, rgba(100, 116, 139, 0.35));
}
.rewards-tile--locked .rewards-tile__medallion {
    background: linear-gradient(140deg, #e2e8f0 0%, #cbd5e1 60%, #94a3b8 100%);
    color: #ffffff;
    filter: grayscale(0.8);
}
.rewards-tile__icon {
    width: 52%;
    height: 52%;
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.3));
}

.rewards-tile__check {
    position: absolute;
    inset-inline-end: -4px;
    inset-block-start: -4px;
    width: 1.125rem;
    height: 1.125rem;
    filter: drop-shadow(0 2px 3px rgba(16, 185, 129, 0.45));
}
.rewards-tile__check svg { width: 100%; height: 100%; }

.rewards-tile__lock {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: inherit;
    background: rgba(15, 23, 42, 0.45);
    color: #ffffff;
}
.rewards-tile__lock svg { width: 1.25rem; height: 1.25rem; }

.rewards-tile__body { min-height: 2.6rem; }
.rewards-tile__name {
    font-size: 0.75rem;
    font-weight: 700;
    color: #0f172a;
    line-height: 1.15;
    letter-spacing: 0.01em;
}
.rewards-tile--locked .rewards-tile__name { color: #64748b; }
.rewards-tile__status {
    margin-top: 0.25rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.rewards-tile__status--earned { color: #059669; }
.rewards-tile__hint {
    margin-top: 0.25rem;
    font-size: 0.6875rem;
    color: #64748b;
    line-height: 1.3;
}

.rewards-strip__encourage {
    margin-top: 1rem;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.75rem 1rem;
    border-radius: 0.75rem;
    background: linear-gradient(135deg, rgba(253, 230, 138, 0.35), rgba(254, 202, 202, 0.25));
    border: 1px dashed rgba(245, 158, 11, 0.4);
    color: #7c2d12;
    font-size: 0.8125rem;
}

/* Dark mode */
.dark .rewards-strip {
    background: #161927;
    border-color: rgba(255, 255, 255, 0.06);
    box-shadow: 0 6px 20px -6px rgba(0, 0, 0, 0.5);
}
.dark .rewards-strip__title { color: #f1f5f9; }
.dark .rewards-strip__subtitle { color: #94a3b8; }
.dark .rewards-strip__link { color: #a5b4fc; }
.dark .rewards-strip__link:hover { background: rgba(129, 140, 248, 0.12); }
.dark .rewards-strip__progress-track { background: rgba(148, 163, 184, 0.12); }
.dark .rewards-strip__progress-count { color: #94a3b8; }
.dark .rewards-tile {
    background: rgba(30, 33, 54, 0.65);
    border-color: rgba(255, 255, 255, 0.06);
}
.dark .rewards-tile--earned {
    background: linear-gradient(160deg, rgba(30, 33, 54, 0.9) 0%, rgba(120, 53, 15, 0.18) 100%);
    border-color: rgba(245, 158, 11, 0.35);
}
.dark .rewards-tile--locked {
    background: repeating-linear-gradient(135deg, rgba(30, 33, 54, 0.7) 0 8px, rgba(22, 25, 39, 0.85) 8px 16px);
}
.dark .rewards-tile__name { color: #e2e8f0; }
.dark .rewards-tile--locked .rewards-tile__name { color: #94a3b8; }
.dark .rewards-tile__hint { color: #94a3b8; }
.dark .rewards-strip__encourage {
    background: linear-gradient(135deg, rgba(120, 53, 15, 0.3), rgba(153, 27, 27, 0.18));
    border-color: rgba(217, 119, 6, 0.4);
    color: #fcd34d;
}

/* ============================================================
   Rewards Mini — compact strip inside user-menu dropdown
   ============================================================ */

.rewards-mini {
    padding: 0.625rem 0.75rem;
}
.rewards-mini__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.rewards-mini__label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #64748b;
}
.rewards-mini__link {
    font-size: 0.6875rem;
    font-weight: 700;
    color: #4f46e5;
    text-decoration: none;
}
.rewards-mini__link:hover { text-decoration: underline; }

.rewards-mini__empty {
    font-size: 0.75rem;
    color: #94a3b8;
    font-style: italic;
    text-align: center;
    padding: 0.25rem 0;
}

.rewards-mini__row {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
}
.rewards-mini__chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 9999px;
    color: #ffffff;
    background: var(--crest-bg, linear-gradient(140deg, #cbd5e1, #64748b));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.45),
        inset 0 -1px 0 rgba(0, 0, 0, 0.2),
        0 2px 5px rgba(15, 23, 42, 0.15);
    transition: transform 0.15s ease;
}
.rewards-mini__chip:hover { transform: translateY(-1px) scale(1.05); }
.rewards-mini__ico {
    width: 62%;
    height: 62%;
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.3));
}
.rewards-mini__more {
    font-size: 0.6875rem;
    font-weight: 700;
    color: #64748b;
    padding: 0.15rem 0.4rem;
    background: rgba(148, 163, 184, 0.15);
    border-radius: 9999px;
}

.dark .rewards-mini__label { color: #94a3b8; }
.dark .rewards-mini__link { color: #a5b4fc; }
.dark .rewards-mini__empty { color: #64748b; }
.dark .rewards-mini__more { background: rgba(148, 163, 184, 0.12); color: #94a3b8; }


/* ── Affiliate attention bell (admin sidebar) ─────────────────────── */
/* Periodic ring-shake: swings for ~1s, rests for ~2s, repeats. */
@keyframes bell-shake {
    0%, 100% { transform: rotate(0); }
    4%  { transform: rotate(16deg); }
    8%  { transform: rotate(-14deg); }
    12% { transform: rotate(12deg); }
    16% { transform: rotate(-10deg); }
    20% { transform: rotate(7deg); }
    24% { transform: rotate(-4deg); }
    28% { transform: rotate(2deg); }
    32% { transform: rotate(0); }
}

.bell-shake {
    animation: bell-shake 3s ease-in-out infinite;
    transform-origin: top center;
}

@media (prefers-reduced-motion: reduce) {
    .bell-shake { animation: none; }
}

/* Settings: invalid field (toggled by settings.js validateSettingsField) */
.settings-input-invalid,
.settings-input-invalid:focus {
    border-color: #ef4444 !important;
    box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15), 0 0 12px rgba(239, 68, 68, 0.12) !important;
}

/* Course page — description box. The description is rich text written (often pasted) by an admin
   and may carry its own text and background colours, which clash with one of the two themes.
   Inside the box every colour comes from the theme; weight, size, lists and alignment are kept. */
.jm-cdesc { padding: 24px 26px; }
.jm-cdesc .jm-prose { max-width: none; margin: 0; }
.jm-cdesc .jm-prose > :first-child { margin-top: 0; }
.jm-cdesc .jm-prose > :last-child { margin-bottom: 0; }
.jm-cdesc .jm-prose [style], .jm-cdesc .jm-prose font, .jm-cdesc .jm-prose [bgcolor] {
    color: inherit !important;
    background-color: transparent !important;
    background-image: none !important;
}
.jm-cdesc .jm-prose a[style] { color: var(--accent-ink) !important; }
@media (max-width: 640px) { .jm-cdesc { padding: 18px 16px; } }

/* Purchase card — the "what do I get" link under the subscription button; a single plan in the modal. */
.jm-pricing__sublink { justify-self: center; padding: 6px 8px; text-decoration: underline; text-underline-offset: 3px; }
.jm-pricing__sublink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.jm-plans--one { grid-template-columns: minmax(0, 1fr); }

/* Purchase card — the coupon field is folded behind a text link (<details>/<summary>). */
.jm-coupon__toggle {
    justify-self: start; width: fit-content; list-style: none; cursor: pointer;
    color: var(--accent-ink); font-size: .9rem; font-weight: 700;
    text-decoration: underline; text-underline-offset: 3px;
}
.jm-coupon__toggle::-webkit-details-marker { display: none; }
.jm-coupon__toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
.jm-coupon[open] > .jm-coupon__toggle { margin-bottom: 8px; text-decoration: none; color: var(--text); }
.jm-coupon .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* Course page — WhatsApp support chip next to "Last updated". */
a.jm-meta-chip--wa { color: var(--wa-ink); background: var(--wa-soft); border-color: var(--wa-border); text-decoration: none; transition: background .18s, border-color .18s; }
a.jm-meta-chip--wa svg { color: var(--wa); }
a.jm-meta-chip--wa:hover { border-color: var(--wa); }
a.jm-meta-chip--wa:focus-visible { outline: 2px solid var(--wa); outline-offset: 2px; }
.jm-meta-chip--wa .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ---------- Broken-image fallback (js/img-fallback.js) ----------
   A failed <img> is hidden and a placeholder takes its box: it copies the image's classes, so the
   size and rounding stay the same. Colours come from theme tokens, so it fits light and dark. */
img[data-img-broken] { display: none !important; }
.jm-img-fallback {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    min-width: 2rem; min-height: 2rem; max-width: 100%;
    overflow: hidden; vertical-align: middle;
    background: linear-gradient(135deg, var(--card2), var(--thumb-bg, var(--card2)));
    color: var(--faint);
}
.jm-img-fallback > svg { width: 40%; height: 40%; max-width: 56px; max-height: 56px; min-width: 16px; min-height: 16px; }
.jm-img-fallback--person { border-radius: 9999px; aspect-ratio: 1 / 1; container-type: size; }
/* The letter scales with the avatar (container units), with a fixed size for older browsers. */
.jm-img-fallback-initial { font-weight: 700; font-size: 1rem; font-size: max(.75rem, 42cqmin); line-height: 1; color: var(--accent-ink); letter-spacing: 0; text-transform: none; }
