/* SchoolCMS – News listing
   The archive body (template-parts/news/news-listing.php): toolbar,
   excerpt list, recent-posts side menu, plus the single article.
   Restyle per site from Figma. */

/* ── Toolbar (news-filters.php) ──────────────────────────── */
/* one form: the search box, then the category dropdown at the right.
   news-filters.js filters the list in place from both; the Go button is
   the no-JS submit and hides once the script runs. The search box went
   with Feedbucket #1003335 on 2026-09-29 and came back the same day at
   Charlie's call, filtering live. */
.newsFilters {
    margin: 0 0 var(--space-xl);

    .newsFilterForm {
        display:   flex;
        flex-wrap: wrap;
        gap:       var(--space-md);
    }

    /* the field and, inside its right end, the file's outline magnifier
       (images/icons/search.svg – the header's own mark) as the submit */
    .newsSearch {
        position: relative;
        flex:     1 1 100%;

        @media (min-width: 576px) {
            flex:      1 1 auto;
            max-width: 440px;
        }
    }

    .newsSearchInput {
        width:         100%;
        padding:       8px 44px 8px 12px;
        border:        1px solid var(--color-grey-300);
        border-radius: var(--border-radius-sm);
        background:    var(--color-white);
        color:         var(--color-grey-800);
        font:          var(--text-16kl);
        appearance:    none;
        transition:    border-color var(--transition-base);

        &::placeholder {
            color:   var(--color-grey-600a);
            opacity: 1;
        }

        &:focus {
            border-color: var(--color-purple);
        }
    }

    .newsSearchSubmit {
        position:         absolute;
        top:              50%;
        right:            14px;
        width:            17px;
        height:           15px;
        padding:          0;
        border:           0;
        translate:        0 -50%;
        background-color: var(--color-purple);
        mask:             url(../../images/icons/search.svg) center / contain no-repeat;
        -webkit-mask:     url(../../images/icons/search.svg) center / contain no-repeat;
        cursor:           pointer;
        transition:       background-color var(--transition-base);

        &:hover,
        &:focus-visible {
            background-color: var(--color-plum);
        }
    }

    .categoryFilter {
        display: flex;
        width:   100%;

        @media (min-width: 576px) {
            width:       auto;
            margin-left: auto;
        }

        select {
            flex:          1;
            min-width:     0;
            padding:       8px 40px 8px 12px;
            border:        1px solid var(--color-grey-300);
            border-radius: var(--border-radius-sm);
            appearance:    none;
            background:    var(--color-white) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23121d21' stroke-width='2'/%3E%3C/svg%3E") no-repeat right 14px center;
            color:         var(--color-grey-800);
            font:          var(--text-16kl);
            cursor:        pointer;

            @media (min-width: 576px) {
                flex: 0 1 auto;
            }
        }

        .filterSubmit {
            margin-left:   var(--space-xs);
            padding:       8px 16px;
            border:        none;
            border-radius: var(--border-radius-sm);
            background:    var(--color-purple);
            color:         var(--color-white);
            cursor:        pointer;

            &:hover {
                background: var(--color-plum);
            }
        }
    }
}

/* ── Results region (news-results.php in news-listing.php) ── */
/* news-filters.js swaps this region's contents for the endpoint's
   render. While a request is out (past 150ms – a quick answer never
   flickers) what is there dims under a spinner, and the script holds the
   region at its current height so the page never jumps under the
   visitor's typing. The spinner is a pseudo-element: no markup to keep
   in step with the swapped list. */
.newsResults {
    position: relative;

    > * {
        transition: opacity var(--transition-base);
    }

    &.loading > * {
        opacity: 0.4;
    }

    &::after {
        content:          '';
        display:          none;
        position:         absolute;
        top:              32px;
        left:             50%;
        width:            40px;
        height:           40px;
        border:           4px solid var(--color-grey-300);
        border-top-color: var(--color-purple);
        border-radius:    50%;
        translate:        -50% 0;
        animation:        newsSpin 0.8s linear infinite;

        @media (prefers-reduced-motion: reduce) {
            animation: newsPulse 1.6s ease-in-out infinite;
        }
    }

    &.loading::after {
        display: block;
    }
}

@keyframes newsSpin {
    to {
        rotate: 360deg;
    }
}

@keyframes newsPulse {
    50% {
        opacity: 0.3;
    }
}

/* ── Excerpt list (news-excerpt.php) ─────────────────────── */
.news-item {
    margin:  0;
    padding: var(--space-lg) 0;
    border-bottom: 1px solid var(--color-grey-300);

    &:first-child {
        border-top: 1px solid var(--color-grey-300);
    }

    /* the thumbnail and the post meta centre on each other's midline */
    .row {
        align-items: center;
    }

    .news-item-image {
        margin-bottom: var(--space-md);

        @media (min-width: 768px) {
            margin-bottom: 0;
        }

        a {
            display: block;
        }

        /* featured images crop to a consistent card – shallower at full
           width on phones, square beside the post meta from tablet up */
        img {
            width:        100%;
            height:       auto;
            aspect-ratio: 3 / 2;
            object-fit:   cover;

            @media (min-width: 768px) {
                aspect-ratio: 1 / 1;
            }
        }
    }

    .news-title {
        margin: 0;
        font:   var(--text-30kl);

        a {
            color:           var(--color-grey-800);
            text-decoration: none;

            &:hover {
                color: var(--color-plum);
            }
        }
    }

    time.date {
        display:        block;
        margin-top:     var(--space-xs);
        font:           var(--text-14kl);
        color:          var(--color-grey-800);
        text-transform: uppercase;
        letter-spacing: 1px;
    }

    .news-item-excerpt {
        margin-top: var(--space-sm);

        p {
            margin: 0;
        }
    }
}

/* ── Fact lines (the <type>-meta.php partials) ───────────── */
/* the label: value pairs an item shows in place of a publish date –
   closing date / contract / salary on a vacancy, head of subject / exam
   board on a subject, position on a staff member – inline on wide
   screens, stacked on phones. Events have their own (events.css). */
.metaList {
    display:    flex;
    flex-wrap:  wrap;
    gap:        var(--space-xs) var(--space-md);
    margin-top: var(--space-xs);
    font:       var(--text-14kl);
    color:      var(--color-grey-800);

    .meta-label {
        font-weight: 700;
        color:       var(--color-grey-800);
    }

    a {
        color: var(--color-plum);
    }

    &.isClosed time {
        text-decoration:       line-through;
        text-decoration-color: var(--color-grey-300);
    }
}

/* ── The body below the breadcrumbs bar ──────────────────── */
/* the listing (news-listing.php) and the single article (single*.php)
   both sit in a .container.newsBody – the page-body rhythm, which this
   name shares with .pageBody: the padding lives once, in
   css/base/content.css, for both */
.newsBody {
    /* blocks rendered INSIDE the article column (the post's content) carry
       their own .container – nested in a grid column its 12px padding would
       push the copy off the grid by a gutter, so it is removed here and the
       block's own .row / .col pair lines the copy up with the column edge */
    .contentBlock .container {
        padding-left:  0;
        padding-right: 0;
        max-width:     none;
    }
}

/* ── Recent-posts side menu (news-sidebar.php) ───────────── */
.newsSidebar {
    /* stacked after the list on small screens; seats on the left of the
       list on desktop, its heading level with the filter bar */
    margin-top: var(--space-xl);

    @media (min-width: 992px) {
        order:         -1;
        margin-top:    0;
        padding-right: var(--space-xl);
    }

    .newsSidebarTitle {
        margin:         0 0 var(--space-md);
        padding-bottom: var(--space-sm);
        border-bottom:  3px solid var(--color-plum);
        font:           var(--text-30kl);
    }

    ul {
        margin:     0;
        padding:    0;
        list-style: none;
    }

    li {
        padding:       var(--space-md) 0;
        border-bottom: 1px solid var(--color-grey-300);
    }

    a {
        display:         block;
        color:           var(--color-grey-800);
        font:            var(--text-16kl);
        text-decoration: none;

        &:hover {
            color: var(--color-plum);
        }
    }

    .date {
        display:        block;
        margin-top:     var(--space-xs);
        font:           var(--text-14kl);
        color:          var(--color-grey-800);
        text-transform: uppercase;
        letter-spacing: 1px;
    }
}

/* ── Single news article (single.php) ────────────────────── */
.single-news article {
    /* the body is a run of blocks, each with .contentBlock's own vertical
       padding – the header and footer add none of their own, or the gaps
       around the first and last block double up */
    .news-header {
        margin-bottom: 0;

        /* the facts line – posts show "Posted:" + date, the CPT singles
           their <type>-meta.php. The featured image is the page banner
           (banner.php), not repeated here. */
        .news-meta {
            font:  var(--text-14kl);
            color: var(--color-grey-800);

            .meta-label {
                font-weight: 700;
                color:       var(--color-grey-800);
            }
        }
    }

    .news-footer {
        display:     flex;
        flex-wrap:   wrap;
        align-items: center;
        gap:         var(--space-sm) var(--space-lg);
        margin-top:  0;
        font:        var(--text-14kl);

        .news-categories a {
            color: var(--color-plum);
        }

        /* the Apply / Book call to action (the <type>-meta.php partials'
           'cta' part) – the end of the copy, not the header */
        .newsCta {
            flex-basis: 100%;
        }
    }
}

/* ── "← Back" link (single*.php) ─────────────────────────── */
/* the last thing in the MAIN column on every single – directly under the
   content where the eye already is, above a hairline – never further down
   the page below the side menu. It reads "Back" and goes BACK, to the page
   the visitor came from: the href stays the archive (JS off, a new tab,
   crawlers) and js/utilities/back-link.js takes over the plain left click
   when they arrived from this site. Rokeby's pattern, 2026-09-22. */
.single-news .newsBack {
    margin-top:  var(--space-md);   /* the last block's own margin does the rest */
    padding-top: var(--space-md);
    border-top:  1px solid var(--color-grey-300);

    .backLink {
        display:         inline-block;
        color:           var(--color-grey-800);
        font:            var(--text-16kl);
        text-decoration: none;

        &:hover {
            color: var(--color-plum);
        }
    }
}
