/*
 * Last School — public site.
 *
 * The logo is a gradient, mint to blue, so the site is built from it: aurora
 * fields behind the opening and the closing, a deep navy band carrying the
 * numbers, tinted blocks between white ones. Sections alternate rather than
 * running as one white page.
 *
 * Type: Manjari (Swathanthra Malayalam Computing, Kerala) for Malayalam,
 * Bricolage Grotesque for English. One face per script.
 *
 * Colour, contrast and target sizes are held to the UX rules: body text at
 * 4.5:1 or better, every control at least 44px, focus always visible, and
 * all motion dropped under prefers-reduced-motion.
 */

:root {
    --paper:  #ffffff;
    --haze:   #eef8fb;   /* palest cyan — tinted bands */
    --haze-2: #e3f2f8;   /* one step deeper — chips, wells */
    --ink:    #052235;   /* deep sea blue-black */
    --ink-2:  #0a3350;   /* the navy band's lighter partner */
    --slate:  #526b7c;
    --mist:   #c2d7e0;
    --sea:    #0072d8;
    --sea-dk: #005cb0;
    --lagoon: #00c4e4;
    --mint:   #00facc;

    --stroke:     linear-gradient(90deg, var(--mint) 0%, var(--lagoon) 45%, var(--sea) 100%);
    --stroke-act: linear-gradient(90deg, var(--mint) 0%, var(--lagoon) 100%);
    --aurora:
        radial-gradient(60% 80% at 8% 12%,  rgba(0, 250, 204, .28), transparent 62%),
        radial-gradient(55% 75% at 92% 8%,  rgba(0, 196, 228, .26), transparent 60%),
        radial-gradient(70% 90% at 70% 95%, rgba(0, 114, 216, .18), transparent 64%);

    --mal: 'Manjari', sans-serif;
    --lat: 'Bricolage Grotesque', 'Manjari', sans-serif;

    --measure: 1140px;
    --gutter: 1.25rem;

    --r:    14px;
    --r-lg: 22px;
    --r-xl: 32px;

    --lift:   0 10px 30px rgba(5, 34, 53, .08);
    --lift-2: 0 18px 44px rgba(5, 34, 53, .14);
    --step: .2s ease;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--lat);
    font-size: 1.0625rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--mint); color: var(--ink); }

:where(a, button, input, textarea, [tabindex]):focus-visible {
    outline: 3px solid var(--sea);
    outline-offset: 3px;
    border-radius: 4px;
}

.mal { font-family: var(--mal); font-size: 1.06em; line-height: 1.45; }

.wrap { width: 100%; max-width: var(--measure); margin-inline: auto; padding-inline: var(--gutter); }

/* ── Type ──────────────────────────────────────────────────────────── */
h1, h2, h3, h4 { margin: 0; line-height: 1.18; font-weight: 700; letter-spacing: -.015em; }

.t-hero  { font-size: clamp(2.4rem, 9vw, 4.4rem); line-height: 1.1; }
.t-h2    { font-size: clamp(1.7rem, 4.2vw, 2.5rem); }
.t-h3    { font-size: clamp(1.15rem, 2.2vw, 1.4rem); }
.lead    { font-size: clamp(1.05rem, 2.1vw, 1.25rem); color: var(--slate); }

/* ── Bands ─────────────────────────────────────────────────────────── */
.band { position: relative; padding-block: 1.75rem; }
.band--tint { background: var(--haze); }
.band--dark { background: var(--ink); color: #fff; }
.band--dark .lead, .band--dark p { color: rgba(255, 255, 255, .8); }

/* A soft aurora wash, drawn from the logo's own colours. */
.band--aurora { background-image: var(--aurora); background-color: var(--paper); }

/* A curved top edge where a tinted band meets a white one. */
.band--curve { border-radius: var(--r-xl) var(--r-xl) 0 0; margin-top: -1px; }

/* ── Section heading ───────────────────────────────────────────────── */
.head { margin-bottom: 1.5rem; }
.head__rule { width: 54px; height: 5px; border-radius: 5px; background: var(--stroke); margin-bottom: 1rem; }

/* The buy call beside the Courses heading. Deliberately the brightest thing
   in the section: it is the one place on the home page that sends someone
   straight to the catalogue to pay. */
.buyall {
    display: inline-flex; align-items: center; gap: 1rem;
    padding: .8rem 1rem .8rem 1.25rem;
    border-radius: 100px;
    background: linear-gradient(100deg, var(--mint), var(--lagoon));
    color: var(--ink); text-decoration: none;
    box-shadow: 0 10px 26px rgba(0, 196, 228, .34);
    transition: transform var(--step), box-shadow var(--step);
    align-self: center;
}
.buyall:hover { transform: translateY(-2px); box-shadow: 0 14px 32px rgba(0, 196, 228, .45); }
.buyall:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }

.buyall__text { display: grid; gap: .1rem; line-height: 1.25; }
.buyall__text b { font-size: 1rem; font-weight: 800; letter-spacing: -.01em; }
.buyall__text span { font-size: .8rem; color: rgba(5, 34, 53, .72); }

.buyall i {
    flex: none;
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--ink); color: #fff;
    font-size: .8rem;
}
.part__title { font-size: 1.7rem; font-weight: 700; line-height: 1.25; margin: 0; }
.part__title.mal { font-family: var(--mal); font-size: 1.85rem; }
.part__note { color: var(--slate); margin: .85rem 0 0; max-width: 46ch; }
.part__note b { color: var(--ink); font-weight: 600; }
.band--dark .part__note { color: rgba(255, 255, 255, .75); }

/* ── Actions ───────────────────────────────────────────────────────── */
.act {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    min-height: 48px;
    padding: .75rem 1.7rem;
    font-family: var(--lat); font-size: 1rem; font-weight: 600;
    color: #fff; background: var(--sea);
    border: 0; border-radius: 100px;
    text-decoration: none; cursor: pointer;
    box-shadow: 0 8px 20px rgba(0, 114, 216, .26);
    transition: transform var(--step), box-shadow var(--step), background var(--step);
}
.act:hover { background: var(--sea-dk); transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0, 114, 216, .34); }

/* The one gradient action: enrolling. Dark text, so it stops at the cyan. */
.act--enrol { background: var(--stroke-act); color: var(--ink); box-shadow: 0 10px 26px rgba(0, 196, 228, .4); }
.act--enrol:hover { background: var(--stroke-act); filter: brightness(.97); }

.act--ghost { background: var(--paper); color: var(--sea-dk); border: 1.5px solid var(--mist); box-shadow: none; }
.act--ghost:hover { background: var(--haze); border-color: var(--sea); transform: translateY(-2px); }

.act--light { background: #fff; color: var(--sea-dk); box-shadow: 0 10px 26px rgba(0, 0, 0, .18); }
.act--light:hover { background: #fff; }

/* Channel membership: a paid step, but not the enrol button, so it gets its
   own warm accent instead of competing with the one gradient on the page. */
.act--member { background: #f0a92c; color: var(--ink); box-shadow: 0 8px 20px rgba(240, 169, 44, .3); }
.act--member:hover { background: #dd9a1f; box-shadow: 0 12px 26px rgba(240, 169, 44, .38); }
.act--whats { background: #25d366; color: var(--ink); box-shadow: 0 8px 20px rgba(37, 211, 102, .32); }
.act--whats:hover { background: #1ebe5a; box-shadow: 0 12px 26px rgba(37, 211, 102, .4); }
.act--whats svg { width: 1.1em; height: 1.1em; }

.act--bar { min-height: 42px; padding: .4rem 1.2rem; font-size: .94rem; box-shadow: none; }
.act--bar:hover { transform: none; box-shadow: none; }

.act-row { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; }

.textlink { color: var(--sea); font-weight: 600; text-decoration: none; border-bottom: 2px solid rgba(0, 114, 216, .25); }
.textlink:hover { border-bottom-color: var(--sea); }

/* ── Masthead ──────────────────────────────────────────────────────── */
.masthead { position: relative; z-index: 50; }

.utility { display: none; background: var(--ink); color: rgba(255, 255, 255, .8); font-size: .85rem; }
.utility__inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 40px; }
.utility__note { margin: 0; }
.utility__note span { color: rgba(255, 255, 255, .58); }
.utility__tools { display: flex; align-items: center; gap: 1.25rem; }
.utility__link { display: inline-flex; align-items: center; gap: .4rem; color: inherit; text-decoration: none; }
.utility__link:hover { color: var(--mint); }
.utility__link svg { width: 1em; height: 1em; }

.langpick { display: inline-flex; border: 1px solid rgba(255, 255, 255, .3); border-radius: 100px; overflow: hidden; }
.langpick a { display: inline-flex; align-items: center; padding: .25rem .75rem; color: inherit; text-decoration: none; font-size: .82rem; }
.langpick a + a { border-left: 1px solid rgba(255, 255, 255, .3); }
.langpick a:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.langpick a[aria-current="true"] { background: var(--stroke-act); color: var(--ink); font-weight: 700; }
.langpick a.mal { font-family: var(--mal); }

.langpick--compact { border-color: var(--mist); }
.langpick--compact a { color: var(--slate); min-height: 40px; padding-inline: .6rem; }
.langpick--compact a + a { border-left-color: var(--mist); }
.langpick--compact a:hover { background: var(--haze); color: var(--ink); }
.langpick--compact a[aria-current="true"] { background: var(--stroke-act); color: var(--ink); }

.masthead__bar {
    position: sticky; top: 0; z-index: 60;
    display: flex; align-items: center; gap: .6rem;
    min-height: 64px;
    background: rgba(255, 255, 255, .92);
    backdrop-filter: saturate(150%) blur(10px);
    border-bottom: 1px solid var(--haze-2);
}
@supports not (backdrop-filter: blur(1px)) { .masthead__bar { background: #fff; } }

.masthead__brand { display: inline-flex; align-items: center; margin-right: auto; }
/* A touch taller on a phone than on the desktop bar: it is two stacked
   lines, and they close up badly below about 32px. */
.brand__word { display: block; height: 34px; width: auto; }

.masthead__nav { display: none; }
.masthead__nav a {
    display: inline-flex; align-items: center; min-height: 44px; padding: 0 .9rem;
    color: var(--slate); text-decoration: none; font-size: .96rem;
    border-radius: 100px; transition: color var(--step), background var(--step);
}
.masthead__nav a:hover { color: var(--ink); background: var(--haze); }
.masthead__nav a[aria-current="page"] { color: var(--sea-dk); background: var(--haze); font-weight: 600; }

.masthead__tools { display: flex; align-items: center; gap: .5rem; }
.masthead__tools .act, .burger, .langpick--compact a { white-space: nowrap; }

.burger { display: inline-flex; align-items: center; gap: .5rem; min-height: 44px; padding: 0 .5rem; font: inherit; font-size: .94rem; color: var(--ink); background: none; border: 0; cursor: pointer; }
.burger__bars { display: inline-flex; flex-direction: column; justify-content: center; gap: 4px; width: 18px; }
.burger__bars span { display: block; height: 2px; border-radius: 2px; background: var(--ink); transition: transform var(--step), opacity var(--step); }
.burger[aria-expanded="true"] .burger__bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__bars span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] .burger__bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.drawer { display: none; background: #fff; border-bottom: 1px solid var(--haze-2); }
.drawer.is-open { display: block; }
.drawer a { display: flex; align-items: center; min-height: 52px; color: var(--ink); text-decoration: none; font-size: 1.05rem; border-bottom: 1px solid var(--haze); }
.drawer a:last-child { border-bottom: 0; }

/* The language pair now sits at the foot of the drawer. .drawer a styles
   every link in here as a 52px list row, which would pull the two halves
   of the control apart - so they are put back inline. */
.drawer__lang { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 60px; }
.drawer__langlabel { color: var(--slate); font-size: .95rem; }
.drawer__lang .langpick a {
    display: inline-flex; min-height: 40px;
    padding-inline: .95rem; font-size: .92rem;
    border-bottom: 0;
}

/* ── Opening ───────────────────────────────────────────────────────── */
.opening { position: relative; overflow: hidden; padding-block: 2.25rem 2.75rem; }
.opening__grid { display: grid; gap: 2.5rem; align-items: center; }
/* The H1 is a full sentence now, not the old two-word line, so it is set a
   step smaller and allowed a wider measure. At the original hero size it
   ran to six lines and pushed the whole offer below the fold. */
.opening__line { margin-bottom: 1rem; font-size: clamp(1.55rem, 3.4vw, 2.3rem); line-height: 1.2; max-width: 24ch; }
.opening__stroke { height: 7px; border-radius: 7px; background: var(--stroke); max-width: 300px; margin: 0 0 1.5rem; transform-origin: left; animation: sweep .9s cubic-bezier(.2,.7,.3,1) both; }
@keyframes sweep { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.opening__english { font-size: clamp(1.1rem, 2.3vw, 1.35rem); font-weight: 500; margin: 0 0 .9rem; max-width: 30ch; }
.opening__detail { color: var(--slate); margin: 0 0 2rem; max-width: 46ch; }

/* ── AI tools drifting beside the opening ────────────────────────────
   Decoration, so it is aria-hidden in the markup and takes no pointer
   events here. Shown from 1320px only: the content column is 1140px, so
   below that there is no gutter wide enough to hold a 54px chip without
   it landing on the headline.

   Three inset steps, used left and right, so the group reads as a loose
   cluster rather than a column. */
.aiorbit { display: none; }

@media (min-width: 1320px) {
    .aiorbit {
        /* Distance from the window edge to the content column, minus the
           chip and a little air: the chip's inner edge then lands just
           outside the text. clamp() stops it leaving the window on a very
           wide screen or crowding the text on a narrow one. */
        --aiorbit-gap: clamp(0.4rem, calc((100vw - var(--measure)) / 2 - 62px), 7rem);

        --aiorbit-0: calc(var(--aiorbit-gap) + 0.6rem);
        --aiorbit-1: var(--aiorbit-gap);
        --aiorbit-2: calc(var(--aiorbit-gap) + 1.6rem);

        display: block;
        position: absolute; inset: 0;
        pointer-events: none;
        z-index: 0;
    }

    /* The hero's own content sits above the chips. */
    .opening__grid { position: relative; z-index: 1; }

    .aiorbit__chip {
        position: absolute;
        width: 54px; height: 54px;
        display: grid; place-items: center;
        border-radius: 16px;
        background: rgba(255, 255, 255, .86);
        border: 1px solid var(--haze-2);
        box-shadow: 0 10px 26px rgba(5, 34, 53, .10);
        backdrop-filter: blur(6px);
        color: var(--sea-dk);
        font-size: 1.15rem;
        animation-name: aiorbit-drift;
        animation-timing-function: ease-in-out;
        animation-iteration-count: infinite;
        animation-direction: alternate;
        will-change: transform;
    }
    .aiorbit__chip img { width: 30px; height: 30px; object-fit: contain; display: block; }
}

@keyframes aiorbit-drift {
    from { transform: translateY(-9px); }
    to   { transform: translateY(9px); }
}

/* Still present, simply still. The guidance is explicit that motion
   preferences are honoured rather than the element being dropped. */
@media (prefers-reduced-motion: reduce) {
    .aiorbit__chip { animation: none; }
}

/* The review's additions: the tagline above the hero, the trust line, the
   audience chooser, the FAQ and the closing band. */
.opening__tagline {
    font-size: .95rem; font-weight: 700; letter-spacing: .01em;
    color: var(--sea-dk); margin: 0 0 .6rem; text-transform: none;
}
.trustline {
    margin: 1.1rem 0 0; font-size: .92rem; color: var(--slate);
    display: flex; flex-wrap: wrap; gap: .45rem; align-items: baseline;
}
.trustline strong { color: var(--ink); }

/* Four cards, one per job. auto-fit so they go 4 / 2 / 1 without a
   breakpoint for each step. */
.whofor { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.whofor__card {
    display: flex; flex-direction: column; gap: .4rem;
    padding: 1.4rem; border: 1px solid var(--mist); border-radius: var(--r-lg, 14px);
    background: var(--paper); text-decoration: none; color: inherit;
    transition: border-color var(--step), transform var(--step), box-shadow var(--step);
}
.whofor__card:hover {
    border-color: var(--sea); transform: translateY(-2px);
    box-shadow: 0 14px 30px rgba(5, 34, 53, .09);
}
.whofor__who  { font-size: 1.05rem; font-weight: 700; }
.whofor__what { color: var(--slate); font-size: .92rem; line-height: 1.5; }
.whofor__to   { margin-top: auto; padding-top: .7rem; color: var(--sea-dk); font-weight: 600; font-size: .88rem; }
.whofor__to i { margin-left: .35rem; font-size: .75rem; }

.faqs { display: grid; gap: .6rem; max-width: 60rem; }
.faq {
    border: 1px solid var(--mist); border-radius: 12px;
    background: var(--paper); padding: 0 1.1rem;
}
.faq[open] { border-color: var(--sea); }
.faq__q {
    cursor: pointer; font-weight: 600; padding: 1rem 0; list-style: none;
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
}
.faq__q::-webkit-details-marker { display: none; }
/* A plus that becomes a minus, so the control reads as expandable without
   an icon font. */
.faq__q::after {
    content: "+"; font-size: 1.3rem; font-weight: 400; color: var(--sea-dk); line-height: 1;
}
.faq[open] .faq__q::after { content: "2"; }
.faq__a { margin: 0; padding: 0 0 1.1rem; color: var(--slate); line-height: 1.65; max-width: 62ch; }

.closing__inner { text-align: center; }
.closing__title { font-size: clamp(1.6rem, 4vw, 2.3rem); margin: 0 0 .6rem; }
.closing__line  { color: var(--slate); margin: 0 auto 1.5rem; max-width: 52ch; }
.closing__acts  { justify-content: center; }

/* The card's two actions: the course page leads, the priced button is the
   shortcut for anyone who has already decided. They share the row and wrap
   on a narrow card rather than overflowing it. */
/* Its own full-width row, under the price. auto-fit puts the two side by
   side when the card is wide enough and stacks them when it is not, both
   full width either way, so the pair never ends up ragged. */
.course__acts {
    flex: 1 1 100%;
    display: grid; gap: .5rem;
    grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
}
.course__view {
    position: relative; z-index: 4;   /* above the banner's stretched link */
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 40px; padding: 0 1rem; border-radius: 100px;
    background: var(--sea); color: #fff; font-weight: 700; font-size: .88rem;
    text-decoration: none; white-space: nowrap;
    transition: background var(--step);
}
.course__view:hover { background: var(--sea-dk); }
.course__view:focus-visible { outline: 3px solid var(--lagoon); outline-offset: 2px; }
/* The same height as its partner, so the pair reads as one control. */
.course__buy--small {
    min-height: 40px; padding: 0 .9rem; font-size: .85rem;
    background: var(--paper); color: var(--sea-dk);
    border: 1.5px solid var(--mist); animation: none;
}
.course__buy--small:hover { border-color: var(--sea); background: var(--haze); }

.colophon__contact { margin: .9rem 0 0; font-size: .9rem; line-height: 1.8; }
.colophon__contact a { color: inherit; text-decoration: none; opacity: .85; }
.colophon__contact a:hover { opacity: 1; text-decoration: underline; }

.course__promise {
    margin: -.2rem 0 .6rem; color: var(--slate); font-size: .88rem; line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* The capped demo: the player fills the box as before, and the gate covers
   it once the free share has been watched. */
.yt-capped { position: relative; }
.yt-capped > div, .yt-capped iframe { width: 100%; height: 100%; border: 0; display: block; }
.yt-gate {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .6rem; padding: 1.5rem; text-align: center;
    background: rgba(5, 34, 53, .93); color: #fff;
    /* Above the player, which is an iframe and therefore its own layer. */
    z-index: 2;
}
.yt-gate__title { margin: 0; font-size: 1.15rem; font-weight: 700; }
.yt-gate__body  { margin: 0; max-width: 34ch; font-size: .92rem; line-height: 1.55; color: rgba(255,255,255,.85); }
.yt-gate__cta   { margin-top: .4rem; }

/* Rating and faces */
.proof { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.25rem; margin-top: 1.75rem; }
.proof__stars { color: #f0a92c; letter-spacing: .08em; }
.proof span { color: var(--slate); font-size: .95rem; }
.proof b { color: var(--ink); }

/* The card that sits beside the opening: real courses, not a stock mock-up. */
.preview {
    position: relative;
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-2);
    padding: 1.1rem;
}
.preview__head { display: flex; align-items: center; gap: .6rem; padding: 0 .3rem .8rem; border-bottom: 1px solid var(--haze); margin-bottom: .8rem; }
.preview__head img { width: 34px; height: 34px; border-radius: 9px; object-fit: cover; }
.preview__head b { display: block; font-size: .95rem; }
.preview__head span { color: var(--slate); font-size: .8rem; }
.preview__row { display: flex; gap: .7rem; align-items: center; padding: .55rem .3rem; }
.preview__row img { width: 40px; height: 40px; border-radius: 9px; object-fit: cover; flex: none; background: var(--haze); }
.preview__row b { display: block; font-size: .87rem; line-height: 1.3; }
.preview__bar { height: 5px; border-radius: 5px; background: var(--haze-2); overflow: hidden; margin-top: .3rem; }
.preview__bar i { display: block; height: 100%; border-radius: 5px; background: var(--stroke-act); }

/* ── The opening's card: the certificate a student finishes with ──────
   Built from the same parts as view_certificate.php - the brand edge down
   the left, the gradient rule, the quarter-circle column - so the opening
   shows the thing that actually arrives rather than a stock mock-up.

   Everything inside is sized against the card's own width (cqw), with a px
   floor first in each declaration: a browser without container queries
   drops the cqw value and keeps the floor, which is tuned for the desktop
   card. That keeps one set of proportions from 320px upwards. */
.certshow { position: relative; }
.certshow__stack { position: relative; }

/* Two sheets behind, so it reads as something issued more than once. */
.certshow__ghost {
    position: absolute; inset: 0;
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r);
    box-shadow: var(--lift);
}
.certshow__ghost--far  { transform: rotate(-6deg)  translate(-2.5%, 3.5%); opacity: .62; }
.certshow__ghost--near { transform: rotate(3deg)   translate(1.6%, 1.8%); opacity: .85; }

.cert-mini {
    position: relative;
    aspect-ratio: 1000 / 707;        /* the real sheet */
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r);
    box-shadow: var(--lift-2);
    overflow: hidden;
    display: flex; flex-direction: column;
    padding: 6.2% 27% max(30px, 5.4%) 8%;   /* right gutter clears the pattern;
                                              the floor keeps the foot clear of
                                              the pill on a narrow card */
    container-type: inline-size;
}

.cert-mini__edge {
    position: absolute; left: 0; top: 0; bottom: 0; width: 1.5%;
    background: linear-gradient(180deg, var(--mint), var(--lagoon) 40%, var(--sea));
}

/* The quarter-circle column: two columns of six square cells. Each cell is
   half the pattern's width, so the whole thing stays fluid with the card. */
.cert-mini__pattern { position: absolute; top: 0; right: 0; width: 23.6%; height: 100%; display: flex; }
.cert-mini__pattern .pat-col { width: 50%; display: flex; flex-direction: column; }
.cert-mini__pattern .pat { width: 100%; aspect-ratio: 1; flex: none; }
.cert-mini__pattern .q-tl { border-top-left-radius: 100%; }
.cert-mini__pattern .q-tr { border-top-right-radius: 100%; }
.cert-mini__pattern .q-bl { border-bottom-left-radius: 100%; }
.cert-mini__pattern .q-br { border-bottom-right-radius: 100%; }
.cert-mini__pattern .c-ink    { background: var(--ink); }
.cert-mini__pattern .c-ink2   { background: var(--ink-2); }
.cert-mini__pattern .c-mint   { background: var(--mint); }
.cert-mini__pattern .c-lagoon { background: var(--lagoon); }
.cert-mini__pattern .c-haze   { background: var(--haze); }
.cert-mini__pattern .c-lime   { background: #cfe84f; }

.cert-mini__logo { display: block; width: auto; align-self: flex-start;
                   height: 20px; height: max(20px, 7.1cqw); }

.cert-mini__title {
    font-weight: 800; letter-spacing: -.02em; line-height: 1;
    margin: 0; margin-top: 7%;
    font-size: 30px; font-size: max(30px, 10.5cqw);
}
.cert-mini__sub { color: var(--slate); margin: 0; font-size: 11px; font-size: max(11px, 3.9cqw); }
.cert-mini__rule {
    display: block; width: 14.2%; border-radius: 99px; margin-top: 3%;
    height: 3px; height: max(3px, .95cqw);
    background: linear-gradient(90deg, var(--mint), var(--lagoon) 55%, var(--sea));
}

.cert-mini__name {
    font-weight: 800; line-height: 1.12; letter-spacing: -.01em;
    margin: 0; margin-top: 5.5%;
    font-size: 18px; font-size: max(18px, 6.2cqw);
}
.cert-mini__for    { color: var(--slate); margin: 0; margin-top: 2.4%; font-size: 8px;  font-size: max(8px, 2.8cqw); }
.cert-mini__course { color: var(--ink-2); font-weight: 700; margin: 0; line-height: 1.3;
                     font-size: 10px; font-size: max(10px, 3.3cqw); }

.cert-mini__foot { margin-top: auto; display: flex; gap: 9%; }
.cert-mini__foot div { min-width: 0; flex: 1; }
.cert-mini__value { font-weight: 700; white-space: nowrap; font-size: 8px; font-size: max(8px, 2.4cqw); }
.cert-mini__sign  { font-family: Georgia, 'Times New Roman', serif; font-style: italic; font-weight: 400;
                    white-space: nowrap; font-size: 11px; font-size: max(11px, 3.3cqw); }
.cert-mini__line  { background: var(--ink); margin-top: 4%; height: 1px; }
.cert-mini__label { display: block; color: var(--slate); text-transform: uppercase; letter-spacing: .1em;
                    margin-top: 3%; font-size: 7px; font-size: max(7px, 2.3cqw); }

/* Says plainly that the name on it is a placeholder. */
/* Clears the bottom-left pill, which hangs 14px below the sheet. */
.certshow__note { margin: 2.5rem .2rem 0; text-align: center; color: var(--slate); font-size: .8rem; }

.pill {
    position: absolute; z-index: 2;
    display: inline-flex; align-items: center; gap: .5rem;
    background: #fff; border-radius: 100px;
    padding: .5rem .9rem;
    box-shadow: var(--lift);
    font-size: .82rem; font-weight: 600;
}
.pill i { color: var(--sea); }
.pill--tr { top: -14px; right: -8px; }
.pill--bl { bottom: -16px; left: -12px; }

/* ── Numbers ───────────────────────────────────────────────────────
   A card rather than a full-width band: it lifts off the aurora above and
   the white below, so the three figures read as one claim instead of a
   stripe of decoration. */
.proof-band { position: relative; padding-bottom: 1.5rem; }

.proof-card {
    position: relative;
    margin-top: -1.5rem;
    background: var(--ink);
    background-image: var(--aurora);
    background-blend-mode: soft-light;
    border-radius: var(--r-lg);
    box-shadow: 0 24px 60px rgba(5, 34, 53, .28);
    padding: 1.6rem 1.4rem 1.4rem;
    color: #fff;
    overflow: hidden;
}

.proof-card__caption {
    margin: 0 0 1.2rem;
    font-size: .8rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .55);
}
.proof-card__caption:lang(ml) { text-transform: none; letter-spacing: 0; font-family: var(--mal); font-size: .95rem; }

.figures { display: grid; gap: 1.4rem; margin: 0; }

.figure { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; gap: 0 .9rem; align-items: center; }
.figure__icon {
    grid-row: span 2;
    width: 44px; height: 44px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, .1);
    color: var(--mint);
    font-size: 1rem;
}
.figure__value {
    margin: 0;
    font-size: clamp(1.7rem, 5.5vw, 2.3rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}
.figure__label { margin: 0; color: rgba(255, 255, 255, .72); font-size: .92rem; }

/* ── Courses ───────────────────────────────────────────────────────── */
.courses { display: grid; gap: 1.1rem; }

.course {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r);
    box-shadow: var(--lift);
    overflow: hidden;
    /* The title and the poster behind it are unbreakable in a narrow column,
       and a grid item defaults to min-width:auto. */
    min-width: 0;
    transition: transform var(--step), box-shadow var(--step), border-color var(--step);
}
.course:hover { transform: translateY(-3px); box-shadow: var(--lift-2); border-color: var(--mist); }

/* ── The banner: the poster, shown ───────────────────────────────────
   These posters are designed artwork with the course name already on them.
   They used to be blurred and covered by a scrim reaching 96% opacity so a
   white title could sit on top, which hid the one thing on the card worth
   looking at. The title moved into the body below and the image is left
   alone.

   16:9 because that is the shape the uploads are: the thumbnails come from
   the same artwork as the YouTube videos. */
.course__banner {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    text-decoration: none; color: #fff;
    overflow: hidden;
    background: var(--ink);
}
/* Stretched over the whole card, so anywhere but the button opens the
   course. The button lifts itself above this. */
.course__banner::after { content: ""; position: absolute; inset: 0; z-index: 3; }

.course__bg {
    display: block;
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}
.course:hover .course__bg { transform: scale(1.04); }

/* ── The title, under the image ──────────────────────────────────────
   Sits in the card body with the facts and the price. .course__body is a
   flex column with its own gap, so no margin here. */
.course__title {
    margin: 0;
    font-size: 1.08rem; font-weight: 700; line-height: 1.3;
    letter-spacing: -.01em;
    color: var(--ink);
    /* Two lines at most: a long name must not push the price out of line
       with the card beside it. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.course__title a { color: inherit; text-decoration: none; }
.course__title a:hover { color: var(--sea); }

/* The admin's pick. Amber rather than the mint used for a discount, so
   the two badges on one card are telling you different things. */
.course__pick {
    position: absolute; z-index: 2; top: .7rem; left: .7rem;
    display: inline-flex; align-items: center; gap: .3rem;
    background: #f0a92c; color: var(--ink);
    border-radius: 100px; padding: .2rem .6rem;
    font-size: .72rem; font-weight: 700;
}
.course__pick i { font-size: .68rem; }

/* Both badges sit on the poster itself now, with no scrim behind them,
   so each needs its own shadow to stay legible over a bright frame. */
.course__pick, .course__flag { box-shadow: 0 2px 10px rgba(5, 34, 53, .4); }

.course__flag {
    position: absolute; z-index: 2; top: .7rem; right: .7rem;
    background: var(--stroke-act); color: var(--ink);
    border-radius: 100px; padding: .2rem .6rem;
    font-size: .74rem; font-weight: 700; letter-spacing: .01em;
}

/* ── Below the banner ───────────────────────────────────────────────── */
/* flex:1 so the body fills whatever height the grid gave the card. Without
   it the column is only as tall as its content, the footer's margin-top:auto
   has no slack to take up, and the price and buttons stop wherever the text
   happens to end - which left them up to 116px apart across one row. */
.course__body { display: flex; flex-direction: column; flex: 1; gap: .7rem; padding: .9rem 1.05rem 1.05rem; }

.course__facts { display: flex; flex-wrap: wrap; gap: .35rem .5rem; margin: 0; }
.course__facts span {
    display: inline-flex; align-items: center;
    background: var(--haze); color: var(--slate);
    border-radius: 100px; padding: .15rem .65rem; font-size: .78rem; font-weight: 500;
}

/* Price and button share the last line, and the button keeps its width when
   the price is long. */
/* The combo card still has a single button and keeps the price-left,
   button-right row. A course card now has two, so .course__acts below
   claims a full row of its own and the price sits above it - squeezing
   both buttons in beside the price made them wrap mid-row and left every
   card in the grid ending at a different place. */
.course__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .7rem; margin-top: auto; }
.course__price { display: flex; align-items: baseline; gap: .4rem; margin: 0; min-width: 0; }
.course__now { font-size: 1.15rem; font-weight: 700; }
.course__price s { color: var(--slate); font-size: .85rem; }

.course__buy {
    position: relative; z-index: 4;   /* above the banner's stretched link */
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 40px; padding: 0 1.05rem;
    border-radius: 100px;
    background: var(--ink); color: #fff;
    font-size: .88rem; font-weight: 700; text-decoration: none;
    white-space: nowrap;
    transition: background var(--step), transform var(--step);
}
.course__buy:focus-visible { outline: 3px solid var(--lagoon); outline-offset: 2px; }

/* A short wiggle on a long interval rather than a button that never stops
   moving: constant motion reads as a fault, and the eye filters it out
   within seconds anyway, so it would draw attention once and then cost
   attention forever. Roughly three quarters of a second of movement in
   every six. */
@keyframes course-buy-nudge {
      0%, 87%, 100% { transform: translateX(0) rotate(0deg); }
     89%            { transform: translateX(-2px) rotate(-1.5deg); }
     91%            { transform: translateX(2px)  rotate(1.5deg); }
     93%            { transform: translateX(-2px) rotate(-1.2deg); }
     95%            { transform: translateX(2px)  rotate(1.2deg); }
     97%            { transform: translateX(-1px) rotate(-.5deg); }
     99%            { transform: translateX(1px)  rotate(.5deg); }
}
.course__buy { animation: course-buy-nudge 6s ease-in-out infinite; }

/* A row of buttons twitching in unison looks like a rendering glitch, so
   each card in a three-up row takes its turn. */
.course:nth-child(3n+2) .course__buy { animation-delay: 2s; }
.course:nth-child(3n+3) .course__buy { animation-delay: 4s; }

/* Not paused - stopped. A paused animation keeps whatever transform it was
   holding, which would fight the hover lift below. And once someone is on
   the button it has already done its job. */
.course__buy:hover,
.course__buy:focus-visible { animation: none; }
.course__buy:hover { background: var(--sea); transform: translateY(-1px); }

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

/* ── Combo offers ────────────────────────────────────────────────────
   A combo card sits in the same grid as the course cards and is built from
   the same parts, so the catalogue stays one thing. What differs is the
   banner: several posters, because the card is selling several courses. */
.combo__banner { background: var(--ink); }

/* A mosaic rather than equal slices: three equal columns of a 16:9 box
   leaves each poster too narrow to recognise, so the first course gets
   most of the frame and the rest stack beside it. */
.combo__stack {
    position: absolute; inset: 0;
    display: grid;
    grid-template-columns: 1.9fr 1fr;
    gap: 2px;
}
.combo__poster {
    width: 100%; height: 100%;
    min-width: 0; min-height: 0;
    object-fit: cover;
    background: var(--ink);
}
/* The lead poster holds the full height of the left column. */
.combo__poster:first-child { grid-row: 1 / -1; }
/* Two in the right column, or one filling it when the combo has only two
   courses. */
.combo__stack:has(.combo__poster:nth-child(3)) { grid-template-rows: 1fr 1fr; }

/* The combo flag takes the top-left slot the featured star uses; a combo is
   never also a featured course, so they cannot collide. */
.combo__flag { background: #6b4bd6; color: #fff; }

.combo__save { color: var(--sea-dk); font-weight: 700; }
.combo__list {
    margin: 0 0 .9rem;
    color: var(--slate); font-size: .86rem; line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The tag on an ordinary course card, pointing at the better deal. */
.course__combo {
    position: relative; z-index: 4;   /* above the banner's stretched link */
    display: flex; align-items: center; gap: .5rem;
    margin: 0 0 .85rem;
    padding: .5rem .7rem;
    border-radius: var(--r);
    background: rgba(107, 75, 214, .09);
    border: 1px solid rgba(107, 75, 214, .22);
    color: #52399f; text-decoration: none;
    font-size: .8rem; font-weight: 700; line-height: 1.35;
}
.course__combo:hover { background: rgba(107, 75, 214, .16); }
.course__combo i { flex: none; font-size: .85rem; }

/* ── The combo's own page ──────────────────────────────────────────── */
.combo__eyebrow {
    display: inline-flex; align-items: center; gap: .45rem;
    background: #6b4bd6; color: #fff;
    border-radius: 100px; padding: .3rem .85rem;
    font-size: .75rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .06em;
}
.combo__headline {
    font-size: clamp(1.7rem, 5vw, 2.8rem);
    font-weight: 800; line-height: 1.1; letter-spacing: -.02em;
    margin: .8rem 0 .6rem;
    text-wrap: balance;
}

.combo__deal {
    display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.5rem;
    margin-top: 1.5rem;
}
.combo__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: .6rem; margin: 0; }
.combo__now { font-size: 2.1rem; font-weight: 800; letter-spacing: -.02em; }
.combo__price s { color: var(--slate); font-size: 1.05rem; }
.combo__price b {
    background: var(--stroke-act); color: var(--ink);
    border-radius: 100px; padding: .25rem .75rem;
    font-size: .85rem; font-weight: 800;
}
.combo__note, .combo__owned {
    margin: 1rem 0 0;
    color: var(--slate); font-size: .95rem;
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
.combo__owned i { color: #0e7c6b; }

.combo__members { display: grid; gap: 1rem; }
.cmember {
    display: grid; grid-template-columns: 110px 1fr; gap: 1rem;
    align-items: center;
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r-lg);
    box-shadow: var(--lift);
    padding: .9rem;
}
.cmember__art { line-height: 0; }
.cmember__art img { width: 100%; height: auto; aspect-ratio: 16/9; object-fit: cover; border-radius: var(--r); background: var(--haze); }
.cmember__body { min-width: 0; }
.cmember__body h3 { margin: 0 0 .3rem; font-size: 1.05rem; line-height: 1.3; }
.cmember__body h3 a { color: inherit; text-decoration: none; }
.cmember__body h3 a:hover { color: var(--sea); }
.cmember__body p { margin: 0; color: var(--slate); font-size: .9rem; }
.cmember__price { margin-top: .4rem !important; font-size: .85rem !important; }
.cmember__owned { color: #0e7c6b; font-weight: 700; }
/* Dimmed, not hidden: it is still part of what the combo contains, it is
   just not part of what this student would be buying. */
.cmember.is-owned { background: var(--haze); box-shadow: none; }

.combo__prose { margin-top: 1.75rem; }

@media (min-width: 700px) {
    .combo__members { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
    .cmember { grid-template-columns: 1fr; }
    .cmember__art img { aspect-ratio: 16/9; }
}

/* ── Reasons ───────────────────────────────────────────────────────── */
.reasons { display: grid; gap: 1.1rem; }
.reason { background: var(--paper); border: 1px solid var(--haze-2); border-radius: var(--r); padding: 1.4rem; box-shadow: var(--lift); }
.reason__icon { width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center; background: var(--haze); color: var(--sea); font-size: 1.1rem; margin-bottom: .9rem; }
.reason__icon--mint { background: rgba(0, 250, 204, .18); color: #04808c; }
.reason__key { display: block; font-family: var(--mal); color: var(--sea); font-weight: 700; margin-bottom: .1rem; }
.reason h3 { font-size: 1.08rem; margin: 0 0 .35rem; }
.reason p { margin: 0; color: var(--slate); font-size: .95rem; }

/* ── Teachers ──────────────────────────────────────────────────────
   Cards sized rather than stretched: with two mentors a four-column grid
   left half the row empty, and with six it should still wrap sensibly. */
.teachers {
    display: grid;
    /* auto-fill, not auto-fit: the empty tracks stay, so two mentors keep the
       card size of six instead of stretching across the row. One column on a
       phone still fills the width. */
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 1.25rem;
}

.teacher {
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r);
    box-shadow: var(--lift);
    overflow: hidden;
    transition: transform var(--step), box-shadow var(--step);
}
.teacher:hover { transform: translateY(-3px); box-shadow: var(--lift-2); }

.teacher__frame { position: relative; background: var(--haze); }
.teacher__photo { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; display: block; }
/* One column: a portrait photo at full width would be half the screen. */
@media (max-width: 560px) {
    .teacher__photo { aspect-ratio: 16 / 10; }
}

/* The role sits on the photo, so the card below stays about the person. */
.teacher__role {
    position: absolute;
    left: .7rem; bottom: .7rem;
    background: rgba(5, 34, 53, .82);
    backdrop-filter: blur(4px);
    color: #fff;
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .02em;
    padding: .25rem .65rem;
    border-radius: 100px;
}

.teacher__body { padding: .9rem 1rem 1.1rem; }
.teacher__name { font-size: 1.02rem; font-weight: 700; margin: 0 0 .35rem; }
.teacher__bio {
    margin: 0;
    color: var(--slate);
    font-size: .88rem;
    line-height: 1.55;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.teacher__links { display: flex; gap: .45rem; margin-top: .9rem; }
.teacher__links a {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--haze);
    color: var(--sea-dk);
    transition: background var(--step), color var(--step);
}
.teacher__links a:hover { background: var(--sea); color: #fff; }
.teacher__links svg { width: 15px; height: 15px; }

/* ── YouTube ───────────────────────────────────────────────────────
   Three newest uploads at full size, then a reel of the rest that moves on
   its own. The reel is one track holding two identical runs: when the first
   run has travelled its own width the second sits exactly where it started,
   so the loop has no seam. */
.ytsection { overflow: hidden; }   /* the reel is wider than the page */

.ytfeature { display: grid; gap: 1.25rem; }

.ytcard { display: flex; flex-direction: column; gap: .6rem; }
.ytcard .yt-lite {
    position: relative; display: block; width: 100%;
    padding: 0; border: 0; cursor: pointer;
    aspect-ratio: 16 / 9;
    border-radius: var(--r); overflow: hidden;
    background: var(--ink); box-shadow: var(--lift);
    transition: transform var(--step), box-shadow var(--step);
}
.ytcard .yt-lite img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ytcard .yt-lite:hover { transform: translateY(-3px); box-shadow: var(--lift-2); }
.ytcard .yt-frame { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: var(--r); }

/* The play badge is drawn, not marked up, so every facade gets one. */
.ytcard .yt-lite::after {
    content: "";
    position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 62px; height: 44px; border-radius: 12px;
    background: rgba(5, 34, 53, .78) no-repeat center /
        22px 22px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E");
    transition: background-color var(--step);
    pointer-events: none;
}
.ytcard .yt-lite:hover::after, .ytcard .yt-lite:focus-visible::after { background-color: #ff0000; }

.ytcard__title {
    font-size: .95rem; font-weight: 600; line-height: 1.45; margin: 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* The title is a link now. It should not look like body copy that happens
   to be clickable, nor shout in link blue over a wall of thumbnails. */
.ytcard__link { color: inherit; text-decoration: none; }
.ytcard__link:hover, .ytcard__link:focus-visible { color: var(--sea-dk); text-decoration: underline; }
.ytcard__link:focus-visible { outline: 3px solid rgba(0, 114, 216, .35); outline-offset: 2px; border-radius: 3px; }

.ytcard--small { width: 232px; flex: none; }
.ytcard--small .ytcard__title { font-size: .85rem; }

.ytreel { margin-top: 2rem; }
.ytreel__track { display: flex; width: max-content; animation: ytreel 70s linear infinite; }
.ytreel__run { display: flex; gap: 1rem; padding-inline: .5rem; }

/* Clicking a moving thumbnail is a coin toss, so it stops on approach. */
.ytreel:hover .ytreel__track,
.ytreel:focus-within .ytreel__track { animation-play-state: paused; }

@keyframes ytreel {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

.ytsection__act { margin-top: 2rem; }
.ytacts { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; }
.ytacts svg { width: 1.1em; height: 1.1em; }

@media (prefers-reduced-motion: reduce) {
    /* Nothing moves; the reel becomes something to push by hand instead, and
       the second run has no job left, so it goes rather than showing every
       video twice to anyone who scrolls far enough. */
    .ytreel { overflow-x: auto; }
    .ytreel__track { animation: none; }
    .ytreel__run[aria-hidden] { display: none; }

    .storyreel { overflow-x: auto; }
    .storyreel__track { animation: none; }
    .storyreel__run[aria-hidden] { display: none; }
}

/* ── Stories ───────────────────────────────────────────────────────
   The quote leads. The old card put a big decorative quote mark in the
   corner and a small star row above the text, which left the testimonial
   itself looking like the least important thing on the card. */
/* The reviews run as a strip rather than a grid. In a grid every card in a
   row took the height of the tallest, so one video review left a block of
   empty white in the card beside it; across a strip each card is its own
   height and the row reads sideways. Same construction as the YouTube reel:
   one track, the run rendered twice, the copy hidden from assistive tech. */
.storyreel { position: relative; overflow: hidden; }
.storyreel__track { display: flex; width: max-content; animation: storyreel 60s linear infinite; }
.storyreel__run { display: flex; align-items: flex-start; gap: 1.1rem; padding-inline: .55rem; }

/* Reading a moving card is impossible, so it stops on approach - and while
   a video or an audio clip inside it is being used. */
.storyreel:hover .storyreel__track,
.storyreel:focus-within .storyreel__track { animation-play-state: paused; }

@keyframes storyreel {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* Under three reviews there is nothing to loop: it holds still and centres. */
.storyreel--still { overflow-x: auto; }
.storyreel--still .storyreel__track { animation: none; width: 100%; }
.storyreel--still .storyreel__run { justify-content: center; flex-wrap: wrap; width: 100%; }

/* A strip needs a fixed card width; the grid used to supply one. */
.storyreel .story { width: min(86vw, 340px); flex: none; }

.story {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--paper);
    border: 1px solid var(--haze-2);
    border-radius: var(--r-lg);
    box-shadow: var(--lift);
    padding: 1.15rem 1.2rem 1.2rem;
    margin: 0;
    /* A grid item defaults to min-width:auto, so the un-wrapping name and
       role in the head pushed the whole column wider than the page and the
       phone scrolled sideways. The clipping is what should give, not the
       layout. */
    min-width: 0;
}
/* A gradient edge, rather than a quote glyph competing with the text. */
.story::before {
    content: ""; position: absolute; inset: 0 auto 0 0;
    width: 4px; border-radius: var(--r-lg) 0 0 var(--r-lg);
    background: var(--stroke-act);
}

.story__stars { color: #f0a92c; font-size: .85rem; letter-spacing: .06em; flex: none; white-space: nowrap; }

.story__quote {
    margin: 0 0 .7rem;
    font-size: .97rem;
    line-height: 1.6;
    color: var(--ink-2);
    /* Long reviews are cut so the cards stay level; the whole thing is one
       click away. The no-js rule below puts it back when the dialog that
       would show it cannot open. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.story__quote.mal { line-height: 1.55; }

/* ── A review with a clip ────────────────────────────────────────────
   The video sits where the eye lands first, because a video review is
   mostly the video; the audio bar sits under the writing, because an
   audio review is mostly the writing with a voice behind it. */
.story__video {
    display: block; position: relative;
    width: 100%; aspect-ratio: 16 / 9;
    margin: 0 0 .85rem;
    padding: 0; border: 0; border-radius: var(--r);
    overflow: hidden; cursor: pointer;
    background: var(--ink);
}
.story__video img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.story__video:hover img { transform: scale(1.04); }

/* The play badge, drawn rather than an image so it stays crisp. */
.story__video::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 0; height: 0;
    transform: translate(-28%, -50%);
    border-left: 17px solid var(--ink);
    border-top: 11px solid transparent;
    border-bottom: 11px solid transparent;
}
.story__video::before {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 52px; height: 52px; transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(255, 255, 255, .94);
    box-shadow: 0 6px 20px rgba(5, 34, 53, .35);
    transition: transform var(--step), background var(--step);
}
.story__video:hover::before { transform: translate(-50%, -50%) scale(1.08); background: #fff; }
.story__video:focus-visible { outline: 3px solid var(--sea); outline-offset: 2px; }

/* The iframe site.js swaps in has to fill the same box. */
.story__video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.story__audio {
    display: flex; align-items: center; gap: .7rem;
    margin: 0 0 .7rem;
    padding: .65rem .8rem;
    background: var(--haze);
    border: 1px solid var(--haze-2);
    border-radius: var(--r);
}
.story__audioicon {
    flex: none; width: 36px; height: 36px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--stroke-act); color: var(--ink);
    font-size: .9rem;
}
.story__audiobody { flex: 1; min-width: 0; display: grid; gap: .3rem; }
.story__audiolabel { font-size: .76rem; font-weight: 600; color: var(--slate); }
/* The native control is wide by default and would push the card out. */
.story__audio audio { width: 100%; max-width: 100%; height: 34px; display: block; }

.story__more {
    display: inline-flex; align-items: center; gap: .4rem;
    font: inherit; font-size: .9rem; font-weight: 600;
    background: none; border: 0; padding: 0;
    margin: 0;
    color: var(--sea-dk); cursor: pointer;
    text-decoration: underline;
}
.story__more:hover { color: var(--sea); }
/* display:inline-flex above beats the [hidden] attribute's display:none,
   so a quote the clamp did NOT cut still offered to be read in full.
   site.js sets .hidden correctly; this lets it take effect. */
.story__more[hidden] { display: none; }
.story__more i { font-size: .78rem; }

/* No script, no dialog, so nothing may be hidden behind one. */
.no-js .story__quote { display: block; overflow: visible; -webkit-line-clamp: unset; }
.no-js .story__more { display: none; }

/* The whole review, in the dialog. */
.story__full { margin: .8rem 0 1.25rem; font-size: 1.05rem; line-height: 1.75; color: var(--ink-2); }
.story__full.mal { line-height: 1.65; }
.story__by--sheet { display: block; border-top: 1px solid var(--haze); padding-top: 1rem; margin: 0; }
.story__by--sheet .story__name, .story__by--sheet .story__role { white-space: normal; }

/* The card head: face, name, role and rating on one line. */
.story__by { display: flex; align-items: center; gap: .6rem; margin: 0 0 .8rem; }
/* Takes the slack so the rating is pushed to the end, and allows the
   name and role to be clipped rather than wrap the head onto two lines. */
.story__who { flex: 1; min-width: 0; }
.story__who > span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.story__face { width: 36px; height: 36px; flex: none; border-radius: 50%; object-fit: cover; background: var(--haze); }
.story__face--letter {
    display: grid; place-items: center;
    background: var(--haze-2); color: var(--sea-dk);
    font-weight: 700; font-size: 1.05rem;
}
.story__name { font-weight: 700; font-size: .92rem; display: block; line-height: 1.3; }
.story__role { color: var(--slate); font-size: .78rem; display: block; }

/* Nothing to show yet: ask, rather than apologise. */
.story--ask { align-items: flex-start; gap: 1rem; }
.story__asktext { margin: 0; color: var(--slate); }

/* ── Session ───────────────────────────────────────────────────────── */
.session { display: grid; gap: 1rem; background: var(--paper); border: 1px solid var(--haze-2); border-left: 4px solid var(--lagoon); border-radius: var(--r); box-shadow: var(--lift); padding: 1.4rem; }
.session time { color: var(--sea); font-weight: 600; font-size: .92rem; display: block; margin-bottom: .3rem; }
.session h3 { font-size: 1.2rem; margin: 0 0 .35rem; }
.session p { color: var(--slate); margin: 0; }
.session__act { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
.session__price { font-size: 1.2rem; font-weight: 700; }

/* ── Closing ───────────────────────────────────────────────────────── */
.closing { position: relative; overflow: hidden; text-align: center; padding-block: 2.25rem; background: var(--ink); color: #fff; }
.closing::before { content: ''; position: absolute; inset: 0; background: var(--aurora); opacity: .55; }
.closing > * { position: relative; }
.closing__line { margin-bottom: .7rem; }
.closing p { color: rgba(255, 255, 255, .82); max-width: 46ch; margin: 0 auto 1.9rem; }

/* ── The docked buy bar ──────────────────────────────────────────────
   A rounded bar held at the bottom of the window, so the offer stays with
   the reader however far they scroll. Centred on the content column rather
   than stretched edge to edge, which keeps it reading as a card on the page
   instead of browser furniture.

   It carries the brand's aurora over the navy rather than sitting flat: at
   this size a plain dark slab reads as a cookie notice, which is the one
   thing a reader has been trained to dismiss without looking. */
.buydock {
    position: fixed; z-index: 60;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(1rem + env(safe-area-inset-bottom));
    width: min(var(--measure), calc(100vw - 1.5rem));
    display: flex; align-items: center; gap: .6rem;
    padding: .6rem .7rem;
    border-radius: var(--r-lg);
    background: linear-gradient(100deg, var(--ink) 0%, var(--ink-2) 58%, #0d4a6b 100%);
    border: 1px solid rgba(255, 255, 255, .14);
    box-shadow: 0 22px 50px rgba(5, 34, 53, .42), 0 0 0 1px rgba(0, 196, 228, .12),
                inset 0 1px 0 rgba(255, 255, 255, .14);
    color: #fff;
    /* The wash is a child, so it has to be clipped to the same radius. */
    overflow: hidden;
    isolation: isolate;
}
.buydock::before {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background: var(--aurora);
    opacity: .75;
    pointer-events: none;
}
.buydock[hidden] { display: none; }

/* Rising into place says "this just arrived" in a way a bar that is simply
   there does not - but only once, and never for a reader who asked for
   less movement. */
@keyframes buydock-rise {
    from { opacity: 0; transform: translate(-50%, calc(100% + 1rem)); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}
/* No fill mode: until it plays - a background tab, a browser that has
   thrown the animation away - the bar sits where it belongs rather than on
   the first keyframe, which is off the bottom of the window. */
.buydock { animation: buydock-rise .5s cubic-bezier(.19, 1, .22, 1); }
@media (prefers-reduced-motion: reduce) { .buydock { animation: none; } }

/* So the footer is still reachable past a bar that floats over it. The
   room goes inside the footer, not under the body: body padding sits after
   the footer and showed as a white band below the navy. */
body.has-buydock .colophon { padding-bottom: 7rem; }

/* Thumb, name and price are one target: the whole left of the bar opens
   the course, not just the button. */
.buydock__main {
    flex: 1; min-width: 0;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "thumb text price buy";
    align-items: center;
    gap: .9rem;
    color: inherit; text-decoration: none;
}
.buydock__thumb {
    grid-area: thumb;
    width: 52px; height: 52px;
    border-radius: 13px;
    object-fit: cover;
    background: rgba(255, 255, 255, .1);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .18), 0 6px 16px rgba(0, 0, 0, .3);
}

.buydock__text { grid-area: text; min-width: 0; display: grid; gap: .18rem; }
.buydock__eyebrow {
    justify-self: start;
    display: inline-flex; align-items: center; gap: .35rem;
    background: #f0a92c; color: var(--ink);
    border-radius: 100px; padding: .12rem .55rem;
    font-size: .66rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .06em;
}
.buydock__eyebrow i { font-size: .6rem; }
/* One line: the bar must not grow taller on a long course name. */
.buydock__title {
    font-weight: 700; font-size: 1.02rem; letter-spacing: -.01em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.buydock__price {
    grid-area: price;
    display: flex; align-items: baseline; gap: .4rem;
    font-weight: 800; font-size: 1.25rem; white-space: nowrap;
}
.buydock__price s { color: rgba(255, 255, 255, .55); font-weight: 400; font-size: .85rem; }
.buydock__price b {
    background: var(--stroke-act); color: var(--ink);
    border-radius: 100px; padding: .1rem .5rem;
    font-size: .7rem; font-weight: 800;
}

/* Shorter than a full-size action: the bar is 68px tall and a 48px button
   inside it leaves no air. */
.buydock__buy { grid-area: buy; min-height: 44px; padding: .6rem 1.4rem; font-size: .98rem; }
.buydock__buy i { font-size: .8rem; transition: transform var(--step); }
.buydock__main:hover .buydock__buy i { transform: translateX(3px); }

.buydock__close {
    flex: none;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    font: inherit; font-size: 1.25rem; line-height: 1;
    background: rgba(255, 255, 255, .1);
    border: 0; border-radius: 50%;
    color: rgba(255, 255, 255, .7);
    cursor: pointer;
    transition: background var(--step), color var(--step);
}
.buydock__close:hover { background: rgba(255, 255, 255, .22); color: #fff; }

/* On a phone the artwork goes and the price moves under the name, which
   keeps the bar to two short lines and still leads with the number. */
@media (max-width: 640px) {
    .buydock { gap: .45rem; padding: .5rem .55rem; }
    .buydock__main {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "text  buy"
            "price buy";
        gap: .1rem .6rem;
    }
    .buydock__thumb,
    .buydock__eyebrow { display: none; }
    .buydock__title { font-size: .92rem; }
    .buydock__price { font-size: 1rem; min-width: 0; overflow: hidden; }
    /* The badge says 8% off; the struck-through original says the same
       thing again, and there is not room for both beside a Malayalam
       button. */
    .buydock__price s { display: none; }
    .buydock__price b { font-size: .64rem; }
    .buydock__buy { min-height: 42px; padding: .55rem 1.05rem; font-size: .92rem; }
    body.has-buydock .colophon { padding-bottom: 6.25rem; }
}

/* ── Footer ────────────────────────────────────────────────────────── */
.colophon { background: var(--ink); color: #cfe0e8; padding-block: 2.25rem 1.5rem; border-top: 1px solid rgba(255, 255, 255, .08); }
.colophon a { color: #cfe0e8; text-decoration: none; }
.colophon a:hover { color: #fff; }
/* On a phone the two link lists pair up: on their own they each filled a
   row and left half the width empty, which made the footer taller than the
   screen. The brand block and the sign-up form keep the full width. */
.colophon__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.9rem 1.25rem; }
.colophon__brand, .colophon__signup { grid-column: 1 / -1; }
/* No plate: the logotype is white, so it sits on the navy as it is. */
.colophon__logo { display: inline-block; line-height: 0; }
.colophon__logo img { height: 30px; width: auto; }

/* The one-line footer, for pages that are selling something. */
.colophon--slim { padding-block: 1.25rem; }
.colophon__slim {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: .6rem 1.4rem;
    text-align: center;
}
.colophon__slimlinks { display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem 1.2rem; font-size: .95rem; }
.colophon__slimlinks a { text-decoration: none; }
.colophon__slimnote { color: rgba(207, 224, 232, .7); font-size: .85rem; }
.colophon__slimnote a { text-decoration: underline; }

@media (min-width: 760px) {
    /* Logotype left, credit right, links in between. */
    .colophon__slim { flex-wrap: nowrap; justify-content: space-between; text-align: left; }
    .colophon__slimlinks { flex: 1; justify-content: center; }
}
.colophon h4 { font-size: .95rem; color: #fff; margin: 0 0 .8rem; }
.colophon ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; font-size: .95rem; }
.colophon__social { display: flex; gap: .55rem; margin-top: 1rem; }
.colophon__social a { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%; background: rgba(255, 255, 255, .1); transition: background var(--step); }
.colophon__social a:hover { background: var(--sea); color: #fff; }

.signup { display: flex; gap: .5rem; margin-top: .8rem; }
.signup input { flex: 1; min-width: 0; font: inherit; font-size: .95rem; padding: .7rem 1rem; border: 1px solid rgba(255, 255, 255, .22); border-radius: 100px; background: rgba(255, 255, 255, .08); color: #fff; }
.signup input::placeholder { color: rgba(207, 224, 232, .6); }
.signup input:focus { outline: none; border-color: var(--lagoon); }
.signup button { font: inherit; font-size: .95rem; font-weight: 700; padding: .7rem 1.2rem; border: 0; border-radius: 100px; background: var(--stroke-act); color: var(--ink); cursor: pointer; }

.colophon__foot { margin-top: 2.25rem; padding-top: 1.25rem; border-top: 1px solid rgba(255, 255, 255, .12); display: flex; flex-wrap: wrap; justify-content: space-between; gap: .6rem; font-size: .87rem; color: rgba(207, 224, 232, .72); }

/* ── Forms, notices, dialog ────────────────────────────────────────── */
.field { margin-bottom: 1rem; }
.field label { display: block; font-weight: 600; font-size: .92rem; margin-bottom: .35rem; }
.input { width: 100%; font: inherit; padding: .8rem 1rem; border: 1px solid var(--mist); border-radius: 12px; background: var(--paper); color: var(--ink); }
.input:focus { outline: none; border-color: var(--sea); box-shadow: 0 0 0 3px rgba(0, 114, 216, .16); }

.field__count { margin: .35rem 0 0; text-align: right; font-size: .8rem; color: var(--slate); }
.field__count.is-full { color: #b3271c; font-weight: 600; }

.notice { padding: .85rem 1rem; border-radius: 12px; font-size: .95rem; margin-bottom: 1.25rem; border-left: 4px solid; }
.notice--ok { background: var(--haze); border-color: var(--sea); }
.notice--bad { background: #fdeceb; border-color: #c0392b; color: #8e2a20; }
.notice--warn { background: #fff6e6; border-color: #b8860b; color: #7a5c06; }

dialog.sheet { border: 0; border-radius: var(--r-lg); padding: 0; width: min(560px, calc(100vw - 2rem)); color: var(--ink); box-shadow: 0 30px 70px rgba(5, 34, 53, .3); }
dialog.sheet::backdrop { background: rgba(5, 34, 53, .55); backdrop-filter: blur(2px); }
.sheet__body { padding: 1.75rem 1.5rem 2rem; }
.sheet__close { position: absolute; top: .7rem; right: .8rem; width: 38px; height: 38px; display: grid; place-items: center; font: inherit; font-size: 1.4rem; background: var(--haze); border: 0; border-radius: 50%; color: var(--slate); cursor: pointer; }
.sheet__close:hover { background: var(--sea); color: #fff; }

.stars { color: #f0a92c; letter-spacing: .06em; }

@media (prefers-reduced-motion: reduce) {
    .opening__stroke { animation: none; }
    *, *::before, *::after { transition: none !important; }
    .course:hover, .act:hover { transform: none; }
}

/* ── From 700px ────────────────────────────────────────────────────── */
@media (min-width: 700px) {
    :root { --gutter: 2rem; }
    .band { padding-block: 2.25rem; }
    .opening { padding-block: 3rem 3.25rem; }
    .proof-card { margin-top: -2.5rem; padding: 2.2rem 2.4rem 2rem; }
    .figures { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0; }
    .figure { padding-inline: 1.75rem; }
    .figure:first-child { padding-left: 0; }
    .figure + .figure { border-left: 1px solid rgba(255, 255, 255, .14); }
    .courses { grid-template-columns: repeat(2, 1fr); }
    .ytfeature { grid-template-columns: repeat(2, 1fr); }
    .reasons { grid-template-columns: repeat(2, 1fr); }
    .story--ask { flex-direction: row; align-items: center; justify-content: space-between; }
    .session { grid-template-columns: 1fr auto; align-items: center; padding: 1.75rem 2rem; }
    .session__act { justify-content: flex-end; }
    .colophon__grid { grid-template-columns: 2fr 1fr 1fr 1.6fr; gap: 2.5rem; }
    .colophon__brand, .colophon__signup { grid-column: auto; }
    .head { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; }
    .head__note { max-width: 34ch; margin: 0; }
}

/* ── From 900px ────────────────────────────────────────────────────── */
@media (min-width: 900px) {
    .utility { display: block; }
    .masthead__nav { display: flex; align-items: center; gap: .15rem; margin-right: .5rem; }
    .burger { display: none; }
    .masthead__bar { min-height: 70px; gap: 1rem; }
    .brand__word { height: 30px; }
    .drawer { display: none !important; }
}

/* ── From 1040px ───────────────────────────────────────────────────── */
@media (min-width: 1040px) {
    .band { padding-block: 2.5rem; }
    .opening { padding-block: 3.75rem 4rem; }
    .opening__grid { grid-template-columns: 1.05fr .95fr; gap: 3.5rem; }
    .courses { grid-template-columns: repeat(3, 1fr); }
    .ytfeature { grid-template-columns: repeat(3, 1fr); }
    .ytcard--small { width: 264px; }
    .reasons { grid-template-columns: repeat(4, 1fr); }
}
