/* =========================================================================
   portal.css - the learning-portal layout.

   STRUCTURE is borrowed from how learning platforms lay themselves out: a
   persistent rail of places on the left, a search bar across the top, and a
   syllabus shown as a numbered PATH rather than a price list.

   COLOUR is not borrowed. Everything here uses the site's existing palette -
   #006400 brand green, #f7fafc / #e2e8f0 greys, #ed8936 for "in production" -
   so the portal reads as the same product as the payroll side, not a
   different site wearing a template.
   ========================================================================= */

:root {
    --pt-green: #006400;
    --pt-green-dark: #004d00;
    --pt-ink: #1a202c;
    --pt-muted: #718096;
    --pt-line: #e2e8f0;
    --pt-wash: #f7fafc;
    --pt-rail-w: 232px;
}

body.portal {
    background: var(--pt-wash);
    padding: 0;
    margin: 0;
}

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

.pt-shell {
    display: flex;
    min-height: 100vh;
    /* flex-start, not stretch: the rail is sticky and sizes itself to the
       viewport, so stretching it to the full document height would defeat
       the stickiness. */
    align-items: flex-start;
}

/* ---- left rail ---- */

.pt-rail {
    width: var(--pt-rail-w);
    flex: 0 0 var(--pt-rail-w);
    color: #fff;
    display: flex;
    flex-direction: column;
    padding: 18px 14px;

    /* PINNED. The rail is the way around the portal, so it must not scroll
       away with the page - a student four screens into a syllabus should not
       have to scroll back up to change section. */
    position: sticky;
    top: 0;
    height: 100vh;

    /* ...and it carries its OWN scroll, but only when it needs one. `auto`
       means a tall screen shows no scrollbar at all, while a short laptop or
       a landscape phone can still reach the last item. */
    overflow-y: auto;
    overscroll-behavior: contain;

    /* THE SAME BAND AS THE HEADER AND THE BANNERS - one 135deg green ramp
       with the ledger ruling over it, at the same 26px pitch as the worksheet
       behind the page. It ran on its own 180deg ramp before, which bottomed
       out much darker than anything else on the site and made the rail read
       as a separate slab bolted to the page.

       SOLID, not translucent. The rail scrolls independently of the page, so
       anything showing through it slides against the content behind it while
       the panel itself stays still - which reads as a rendering fault rather
       than as depth. The ruling gives it the worksheet texture without that
       cost. */
    background-color: #00570a;
    background-image: repeating-linear-gradient(
            to bottom,
            transparent 0,
            transparent 25px,
            rgba(255, 255, 255, 0.07) 25px,
            rgba(255, 255, 255, 0.07) 26px
        ),
        repeating-linear-gradient(
            to right,
            transparent 0,
            transparent 25px,
            rgba(255, 255, 255, 0.07) 25px,
            rgba(255, 255, 255, 0.07) 26px
        ),
        linear-gradient(135deg, #006400 0%, #00520a 55%, #003d06 100%);
    border-right: 1px solid rgba(255, 255, 255, 0.12);
}

/* A thin scrollbar, in the rail's own colours - the default one is a grey
   slab down the middle of the brand panel. */
.pt-rail {
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.35) transparent;
}

.pt-rail::-webkit-scrollbar {
    width: 6px;
}

.pt-rail::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.3);
    border-radius: 3px;
}

.pt-rail::-webkit-scrollbar-track {
    background: transparent;
}

/* The brand stays put while the rest of the rail scrolls under it, so the way
   home is never scrolled off a short screen. */
.pt-brand {
    position: sticky;
    top: -18px;
    z-index: 2;
    background: linear-gradient(180deg, #00570a 70%, rgba(0, 87, 10, 0));
    margin: -18px -14px 0;
    padding: 18px 22px 14px;
}

.pt-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #fff;
    text-decoration: none;
    padding: 4px 8px 18px;
}

.pt-brand-mark {
    width: 34px;
    height: auto;
    border-radius: 6px;
}

.pt-brand strong {
    display: block;
    font-size: 1rem;
    line-height: 1.2;
}

.pt-brand small {
    display: block;
    font-size: 0.74rem;
    opacity: 0.75;
}

.pt-nav {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pt-nav a {
    display: flex;
    align-items: center;
    gap: 10px;
    /* 44px tall - a thumb target, since the rail is a slide-over on a phone */
    padding: 12px 12px;
    border-radius: 10px;
    color: rgba(255, 255, 255, 0.88);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 500;
    transition: background 0.15s, color 0.15s;
}

.pt-nav a:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
}

.pt-nav a.on {
    background: #fff;
    color: var(--pt-green);
    font-weight: 700;
}

.pt-rail-foot {
    margin-top: auto;
    padding-top: 18px;
}

.pt-help {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    padding: 12px;
    font-size: 0.8rem;
    line-height: 1.5;
}

.pt-help strong {
    display: block;
    margin-bottom: 4px;
}

.pt-help span {
    opacity: 0.85;
}

/* ---- main column ---- */

.pt-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.pt-top {
    display: flex;
    align-items: center;
    gap: 12px;
    background: #fff;
    border-bottom: 1px solid var(--pt-line);
    padding: 12px 22px;
    position: sticky;
    top: 0;
    z-index: 20;
}

.pt-burger {
    display: none;
    background: var(--pt-wash);
    border: 1px solid var(--pt-line);
    border-radius: 10px;
    font-size: 1.1rem;
    padding: 10px 13px;
    cursor: pointer;
    color: var(--pt-ink);
}

.pt-search {
    position: relative;
    flex: 1 1 auto;
    max-width: 520px;
}

.pt-search-icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.9rem;
    opacity: 0.6;
}

.pt-search input {
    width: 100%;
    padding: 11px 14px 11px 40px;
    border: 1px solid var(--pt-line);
    border-radius: 22px;
    background: var(--pt-wash);
    /* 16px so focusing it does not zoom the page on iOS */
    font-size: 16px;
}

.pt-search input:focus {
    outline: none;
    border-color: var(--pt-green);
    background: #fff;
}

.pt-top-cta {
    margin-left: auto;
    background: var(--pt-green);
    color: #fff;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.88rem;
    padding: 11px 18px;
    border-radius: 22px;
    white-space: nowrap;
}

.pt-body {
    flex: 1 1 auto;
    padding: 24px 22px 40px;
    max-width: 1180px;
    width: 100%;
}

.pt-foot {
    padding: 0 22px 24px;
    max-width: 1180px;
}

.pt-crumb {
    color: var(--pt-muted);
    font-size: 0.86rem;
    margin: 0 0 14px;
}

.pt-crumb a {
    color: var(--pt-green);
    text-decoration: none;
}

.pt-h1 {
    font-size: 1.6rem;
    color: var(--pt-ink);
    margin: 0 0 6px;
    line-height: 1.3;
}

.pt-sub {
    color: var(--pt-muted);
    font-size: 0.95rem;
    line-height: 1.65;
    margin: 0 0 18px;
}

.pt-hint {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    background: #fff;
    border: 1px solid var(--pt-line);
    border-left: 4px solid var(--pt-green);
    border-radius: 10px;
    padding: 12px 14px;
    color: #4a5568;
    font-size: 0.88rem;
    line-height: 1.6;
    margin-bottom: 20px;
}

.pt-section {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin: 26px 0 14px;
}

.pt-section h2 {
    font-size: 1.12rem;
    color: var(--pt-ink);
    margin: 0;
}

.pt-section .pt-count {
    color: var(--pt-muted);
    font-size: 0.85rem;
}

/* ---- the learning path ---- */

.path {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
    gap: 16px;
}

.path-node {
    position: relative;
    background: #fff;
    border: 1px solid var(--pt-line);
    border-radius: 14px;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-decoration: none;
    transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
}

.path-node:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.09);
    border-color: var(--pt-green);
}

.path-node.is-open {
    border-color: var(--pt-green);
    box-shadow: 0 0 0 3px rgba(0, 100, 0, 0.12);
}

.pn-num {
    position: absolute;
    top: -10px;
    left: -8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--pt-green);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.path-node.is-pending .pn-num {
    background: #ed8936;
}

.pn-thumb {
    position: relative;
    border-radius: 10px;
    overflow: hidden;
    background: #0f1512;
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
}

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

.pn-thumb-blank {
    color: #4a5568;
    font-size: 1.8rem;
}

.pn-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.25);
}

.pn-play span {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.94);
    color: var(--pt-green);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    padding-left: 3px;
}

.pn-title {
    font-size: 0.94rem;
    font-weight: 600;
    color: var(--pt-ink);
    line-height: 1.35;
}

.pn-kind {
    color: var(--pt-muted);
    font-size: 0.8rem;
}

.pn-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: auto;
    padding-top: 4px;
}

.chip {
    font-size: 0.73rem;
    font-weight: 600;
    padding: 4px 9px;
    border-radius: 20px;
    white-space: nowrap;
    background: var(--pt-wash);
    color: #4a5568;
    border: 1px solid var(--pt-line);
}

.chip-included {
    background: #f0fff4;
    color: #276749;
    border-color: #9ae6b4;
}

.chip-preview {
    background: var(--pt-green);
    color: #fff;
    border-color: var(--pt-green);
}

.chip-pending {
    background: #fffaf0;
    color: #c05621;
    border-color: #fbd38d;
}

.chip-assets {
    letter-spacing: 2px;
}

/* ---- paper cards on the catalogue ---- */

.pt-courses {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
}

.course-card {
    background: #fff;
    border: 1px solid var(--pt-line);
    border-radius: 14px;
    overflow: hidden;
    text-decoration: none;
    display: flex;
    flex-direction: column;
    transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
}

.course-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.1);
    border-color: var(--pt-green);
}

.cc-thumb {
    position: relative;
    aspect-ratio: 16 / 9;
    background: #0f1512;
}

/* Signed-in student: is this course open to them? (owner, 2026-10-04).
   Visitors see neither the badge nor the outline. */
.course-card.is-open { border-color: var(--pt-green); box-shadow: 0 0 0 2px rgba(20, 107, 47, 0.18); }
.cc-access {
    position: absolute; left: 12px; bottom: 12px; z-index: 2;
    padding: 4px 11px; border-radius: 999px;
    font-size: 0.75rem; font-weight: 800; letter-spacing: 0.01em;
}
.cc-access.open { background: #e7f6ec; color: #14532d; }
.cc-access.locked { background: rgba(0, 0, 0, 0.55); color: #fff; }
.cc-price.cc-open { font-size: 0.88rem; }

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

.cc-code {
    position: absolute;
    top: 10px;
    left: 10px;
    background: var(--pt-green);
    color: #fff;
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: 0.5px;
    padding: 4px 10px;
    border-radius: 6px;
}

.cc-body {
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}

.cc-title {
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--pt-ink);
    line-height: 1.3;
}

.cc-meta {
    color: var(--pt-muted);
    font-size: 0.83rem;
}

.cc-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: auto;
    padding-top: 10px;
}

.cc-price {
    color: var(--pt-green);
    font-weight: 800;
    font-size: 1.02rem;
}

.cc-go {
    background: var(--pt-wash);
    border: 1px solid var(--pt-line);
    border-radius: 20px;
    padding: 7px 14px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--pt-ink);
}

/* ---- progress ---- */

.pt-progress {
    background: #fff;
    border: 1px solid var(--pt-line);
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 18px;
}

.pt-progress-top {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 0.86rem;
    color: #4a5568;
    margin-bottom: 8px;
}

.pt-bar {
    height: 8px;
    border-radius: 6px;
    background: var(--pt-line);
    overflow: hidden;
}

.pt-bar span {
    display: block;
    height: 100%;
    background: var(--pt-green);
}

/* ---- responsive ---- */

@media (max-width: 900px) {
    .pt-rail {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 40;
        height: 100vh;
        transform: translateX(-100%);
        transition: transform 0.22s ease;
        box-shadow: 0 0 40px rgba(0, 0, 0, 0.3);
        /* Opaque as a slide-over: it sits ON TOP of the page here rather than
           beside it, and translucency over moving content is unreadable. */
        background-color: #00570a;
        backdrop-filter: none;
    }

    .pt-rail.open {
        transform: translateX(0);
    }

    .pt-burger {
        display: block;
    }

    .pt-body {
        padding: 18px 14px 34px;
    }

    .pt-top {
        padding: 10px 14px;
    }

    .pt-top-cta {
        display: none;
    }

    .pt-h1 {
        font-size: 1.32rem;
    }
}

/* The portal sits on the same worksheet grid as the rest of the app, so the
   two halves read as one product rather than two sites. */
body.portal {
    background-color: #f6f8f6;
    background-image: linear-gradient(to right, rgba(0, 80, 0, 0.06) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(0, 80, 0, 0.06) 1px, transparent 1px);
    background-size: 26px 26px;
    background-attachment: fixed;
}

/* The rail and the top bar are opaque, so the grid runs behind the reading
   column only - a grid behind the navigation would just be noise. */
.pt-top {
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: saturate(1.2) blur(6px);
}

/* =========================================================================
   BANNERS - the artwork on a video card.

   A gradient with an emoji on it is a placeholder, not a banner. This builds
   a real one out of four layers, all of them markup, so there is still
   nothing to store, upload or regenerate:

     1. the unit's own gradient, swept at its own angle
     2. LEDGER RULING - evenly spaced lines with a double rule near the foot,
        the way an accounting ledger is printed. On brand for the subject and
        it stops the large flat colour looking empty.
     3. a huge ghost unit number, bled off the corner
     4. the motif, the paper chip, an accent bar and the title

   Colours and the angle arrive as custom properties from banners.py, so the
   palette lives in one place and this file never names a colour per unit.
   ========================================================================= */

.bn {
    position: relative;
    display: block;
    overflow: hidden;
    background: linear-gradient(var(--ang, 135deg), var(--c1) 0%, var(--c2) 100%);
    isolation: isolate;
}

/* The ledger ruling that used to sit here has gone. On a large flat panel it
   reads as texture; on a small card behind a centred title it reads as noise
   competing with the words. The worksheet grid still runs behind the PAGE, so
   the accounting surface is kept where it works. */

/* Layer 3 - the ghost number, bled off the bottom-right corner. */
.bn::after {
    content: attr(data-num);
    position: absolute;
    /* Bottom LEFT: the play badge took the right corner when the title moved
       to the middle, and a 6rem number under a 38px button is a muddle. */
    left: -8px;
    bottom: -34px;
    font-size: 6.2rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -4px;
    color: rgba(255, 255, 255, 0.13);
    pointer-events: none;
}

.bn-motif {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.22);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
    line-height: 1;
    transition: transform 0.25s ease, background 0.25s ease;
}

.path-node:hover .bn-motif,
.course-card:hover .bn-motif {
    transform: translateY(-2px) scale(1.08);
    background: rgba(255, 255, 255, 0.26);
}

.bn-num {
    position: absolute;
    top: 12px;
    left: 12px;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 1.2px;
    color: rgba(255, 255, 255, 0.92);
    background: rgba(0, 0, 0, 0.22);
    border: 1px solid rgba(255, 255, 255, 0.18);
    padding: 4px 9px;
    border-radius: 6px;
}

/* THE TITLE SITS IN THE MIDDLE OF THE BANNER.
   It used to hug the bottom-left corner, which left the whole upper two
   thirds of every card empty and made the name read as a caption under a
   picture rather than as the subject of the card.

   Centred vertically with a transform rather than flexbox, because the clamp
   below needs `display: -webkit-box` and an element cannot be both. */
.bn-title {
    position: absolute;
    left: 14px;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    color: #fff;
    font-size: 1.02rem;
    font-weight: 700;
    line-height: 1.3;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
    padding-top: 12px;
    /* Three lines then ellipsis - centred titles have the full width now, so
       they can afford one more line than the old corner position could. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The accent rule, now centred above the title. */
.bn-title::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 34px;
    height: 3px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.75);
}

/* The play badge: a ring that fills on hover, so the card reads as a video
   rather than as a coloured tile. */
.pn-thumb.bn .pn-play {
    background: transparent;
    transition: background 0.2s ease;
}

/* The badge moves out of the centre, because the title is there now. Bottom
   right keeps it clear of the code chip and the motif as well. */
.pn-thumb.bn .pn-play {
    inset: auto 10px 10px auto;
    width: 38px;
    height: 38px;
}

.pn-thumb.bn .pn-play span {
    width: 38px;
    height: 38px;
    font-size: 0.85rem;
    background: rgba(255, 255, 255, 0.18);
    border: 2px solid rgba(255, 255, 255, 0.85);
    color: #fff;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
    transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.path-node:hover .pn-play span {
    background: #fff;
    color: var(--pt-green);
    transform: scale(1.1);
}

/* ---- the wide hero above a paper preview ---- */

.hero-bn {
    display: flex;
    align-items: center;
    gap: 18px;
    background: linear-gradient(var(--ang, 135deg), var(--c1) 0%, var(--c2) 100%);
    border-radius: 14px 14px 0 0;
    padding: 22px;
    color: #fff;
    position: relative;
    overflow: hidden;
}

.hero-bn::after {
    content: attr(data-num);
    position: absolute;
    right: 14px;
    bottom: -18px;
    font-size: 4.4rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -3px;
    color: rgba(255, 255, 255, 0.12);
    pointer-events: none;
}

.hb-motif {
    font-size: 2.1rem;
    line-height: 1;
    position: relative;
    width: 58px;
    height: 58px;
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.22);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.hb-text {
    position: relative;
    min-width: 0;
}

.hb-kicker {
    display: block;
    font-size: 0.72rem;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    opacity: 0.88;
}

.hb-title {
    margin: 3px 0 0;
    font-size: 1.4rem;
    line-height: 1.2;
}

/* The hero sits directly on the player, so square off the join. */
.hero-bn + .pv {
    margin-top: 0;
    border-radius: 0 0 14px 14px;
}

.cc-thumb .cc-code {
    z-index: 2;
}

/* The package strip is reference material below the courses, not the first
   thing between a student and the syllabus - so it reads smaller and calmer. */
.tier-strip .tier-card {
    padding: 16px 14px 14px;
}

.tier-strip .tier-icon {
    font-size: 1.5rem;
}

.tier-strip .tier-price {
    font-size: 1.35rem;
    margin-bottom: 6px;
}

.tier-strip .tier-blurb {
    font-size: 0.82rem;
    margin-bottom: 0;
}

/* The monthly and lifetime cards lead to the plans, so they are links. */
.tier-strip a.tier-card {
    color: inherit;
    text-decoration: none;
}

.tier-strip a.tier-card:hover {
    border-color: #006400;
}

/* =========================================================================
   PHONES
   Most students will meet this on a phone, on a patchy connection, standing
   up. Everything below is about that, not about looking neat in a narrow
   browser window on a desktop.
   ========================================================================= */

@media (max-width: 700px) {
    /* A fixed background attachment janks badly while scrolling on iOS Safari
       and is sometimes painted at the wrong scale. The grid is decoration -
       it must never cost a phone its scroll performance. */
    body.portal {
        background-attachment: scroll;
    }

    .pt-body,
    .pt-foot {
        padding-left: 14px;
        padding-right: 14px;
    }

    /* One card per row. Two columns of 160px reads as a grid of stamps and
       makes every title clamp to nothing. */
    .path,
    .pt-courses {
        grid-template-columns: 1fr;
        gap: 12px;
    }

    /* The unit number sits half outside the card; at the screen edge that
       clipped it, so bring it inside. */
    .pn-num {
        top: 8px;
        left: 8px;
    }

    .pn-thumb.bn .bn-num {
        left: 44px;
    }

    .bn-motif {
        font-size: 3.6rem;
    }

    .hero-bn {
        gap: 12px;
        padding: 16px;
    }

    .hb-title {
        font-size: 1.15rem;
    }

    .hb-motif {
        font-size: 2rem;
    }

    /* A sticky bar plus a slide-over rail plus a video is a lot of furniture
       on a 640px-tall screen - let the page scroll it away. */
    .pt-top {
        position: static;
    }
}

/* The rail is a slide-over on a phone, so it needs something to close against
   or a mis-tap leaves the student stuck behind it. */
@media (max-width: 900px) {
    .pt-rail::after {
        content: '';
        position: fixed;
        inset: 0 0 0 var(--pt-rail-w);
        background: rgba(0, 0, 0, 0.45);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.22s ease;
    }

    .pt-rail.open::after {
        opacity: 1;
        pointer-events: auto;
    }
}

/* =========================================================================
   LEVELS, COMING-SOON PAPERS, AND SEARCH HITS
   ========================================================================= */

.level-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin: 20px 0 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--pt-line);
}

.level-chip {
    background: var(--pt-green);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 20px;
    white-space: nowrap;
}

.level-name {
    margin: 0;
    font-size: 1.02rem;
    color: var(--pt-ink);
}

.level-meta {
    margin-left: auto;
    color: var(--pt-muted);
    font-size: 0.82rem;
}

/* A paper that has not been recorded. Present and readable, but visibly not
   for sale - it must never look clickable-but-broken. */
.course-card.is-soon {
    border-style: dashed;
    background: rgba(255, 255, 255, 0.6);
    cursor: default;
}

.course-card.is-soon:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--pt-line);
}

.cc-thumb.bn.is-soon {
    background: repeating-linear-gradient(135deg, #e8ece9 0 12px, #e2e7e3 12px 24px);
}

.cc-thumb.bn.is-soon::after {
    color: rgba(0, 0, 0, 0.07);
}

.cc-thumb.bn.is-soon .bn-title {
    color: #4a5568;
    text-shadow: none;
}

.cc-thumb.bn.is-soon .bn-title::before {
    background: #a0aec0;
}

.cc-thumb.bn.is-soon .cc-code {
    background: #a0aec0;
}

.cc-go.is-muted {
    color: var(--pt-muted);
    background: transparent;
    border-style: dashed;
}

/* search hits inside a result card */
.cc-hits {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-bottom: 6px;
}

.cc-hit {
    font-size: 0.8rem;
    color: #4a5568;
    background: var(--pt-wash);
    border-radius: 6px;
    padding: 4px 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cc-hit.more {
    background: transparent;
    color: var(--pt-muted);
    font-style: italic;
}

@media (max-width: 700px) {
    .level-meta {
        margin-left: 0;
        width: 100%;
    }
}

/* The search needs a visible action. Without one the field submitted on
   Enter alone, which is invisible on a desktop and awkward on a phone. */
.pt-search {
    display: flex;
    align-items: center;
    gap: 0;
}

.pt-search input {
    padding-right: 96px;
}

.pt-search-go {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    background: var(--pt-green);
    color: #fff;
    border: 0;
    /* 36px tall inside a 44px field - the field itself is the tap target */
    padding: 9px 16px;
    border-radius: 18px;
    font: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
}

.pt-search-go:hover {
    background: #00520a;
}

.pt-search-clear {
    position: absolute;
    right: 92px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--pt-muted);
    text-decoration: none;
    font-size: 1.2rem;
    line-height: 1;
    padding: 6px 8px;
}

.pt-search-clear:hover {
    color: var(--pt-ink);
}

@media (max-width: 700px) {
    /* On a narrow bar the word costs more than it earns - the magnifier is
       already understood, and the field keeps its full width for typing. */
    .pt-search-go {
        font-size: 0;
        padding: 10px 12px;
    }

    .pt-search-go::before {
        content: '🔍';
        font-size: 0.95rem;
    }

    .pt-search input {
        padding-right: 56px;
    }

    .pt-search-clear {
        right: 52px;
    }
}
