/* ---------------------------------------------------------------
   Design tokens
   --------------------------------------------------------------- */

:root {
    color-scheme: light dark;

    /* Colour */
    --color-bg: #ffffff;
    --color-surface: #f6f7f9;
    --color-text: #434852;
    --color-text-strong: #1f232b;
    --color-text-muted: #6b7280;
    --color-border: #e4e5e9;
    --color-accent: #c81e1e;
    --color-accent-hover: #9b1616;
    --color-focus: #1f6feb;
    --color-overlay: rgba(0, 0, 0, 0.85);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.08);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.1);

    /* Type — scales continuously instead of jumping at breakpoints */
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
    --text-sm: 0.875rem;
    --text-base: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
    --text-lg: clamp(1.125rem, 1.05rem + 0.35vw, 1.375rem);
    --text-title: clamp(1.6rem, 1.25rem + 1.6vw, 2.25rem);
    /* Scales down further on phones than the other headings: the branding
       block has to share its row with a logo that stays roughly fixed. */
    --text-site-title: clamp(1.25rem, 0.85rem + 1.7vw, 2.6rem);
    --text-site-description: clamp(0.75rem, 0.68rem + 0.3vw, 0.9375rem);
    --text-hero: clamp(1.75rem, 1.1rem + 2.8vw, 3rem);

    /* Spacing */
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2.5rem;
    --space-2xl: 4rem;

    /* Shape */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;

    /* Layout. The text column sits inset from the header and hero above it,
       roughly where it has always sat, rather than running the full page. */
    --width-page: min(1100px, 92vw);
    --width-text: min(760px, 92vw);
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-bg: #14161a;
        --color-surface: #1c1f26;
        --color-text: #c6ccd6;
        --color-text-strong: #f2f4f7;
        --color-text-muted: #98a0ae;
        --color-border: #2b2f38;
        --color-accent: #f26a6a;
        --color-accent-hover: #f79999;
        --color-focus: #6aa3ff;
        --color-overlay: rgba(0, 0, 0, 0.92);

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);
    }
}

/* ---------------------------------------------------------------
   Base
   --------------------------------------------------------------- */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.65;
    color: var(--color-text);
    background-color: var(--color-bg);
    -webkit-font-smoothing: antialiased;

    /* Keeps the footer at the bottom of short pages without position: fixed. */
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

img {
    max-width: 100%;
    height: auto;
}

/* Content rendered from data files stays hidden until it has loaded. */
[hidden] {
    display: none !important;
}

a {
    color: var(--color-accent);
    text-decoration: none;
}

a:hover {
    color: var(--color-accent-hover);
    text-decoration: underline;
}

:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

.skip-link {
    position: absolute;
    top: 0;
    left: 0;
    background: var(--color-text-strong);
    color: var(--color-bg);
    padding: var(--space-xs) var(--space-md);
    z-index: 100;
    /* Offset by its own height, so a taller link can never peek into view
       the way a fixed -40px offset allowed. */
    transform: translateY(-100%);
}

.skip-link:focus {
    transform: translateY(0);
}

.site-wrapper {
    max-width: var(--width-page);
    width: 100%;
    margin: 0 auto;
    flex: 1;
}

/* ---------------------------------------------------------------
   Header
   --------------------------------------------------------------- */

/* No border-bottom: the <hr> below is the visible divider, and a second one
   sat redundantly beneath it. */
.site-header {
    padding: var(--space-lg) 0;
}

/* This rule's only job is the gap above the divider. The <hr> itself has no
   styling of its own, so its ~8px default margin left it crowding the
   branding; the gap now opens up as the viewport widens, where the header
   has room to breathe and the tightness was most obvious. */
.site-header hr {
    margin-top: clamp(var(--space-sm), 2.5vw, var(--space-xl));
}

.header-wrap {
    padding: 0 var(--space-md);
}

.header-grid {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    flex-wrap: wrap;
}

.site-branding {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    min-width: 0;
    /* Pushes the actions to the far side without space-between, which would
       also have spread the actions apart from each other. */
    margin-right: auto;
}

/* The social links and the nav were separate flex children, so once the row
   ran out of space the nav wrapped on its own and left the icons behind.
   Grouping them into one child means they cannot be split: they sit together
   at every width, and drop to the next line together. */
.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/* Keep the mark from being squeezed when the row runs short of space; the
   wordmark next to it is what should give way. */
.site-logo-img {
    flex-shrink: 0;
}

.site-logo-img img {
    /* Deliberately narrow range — the logo holds its size while the wordmark
       beside it does the shrinking. */
    width: clamp(60px, 6vw, 76px);
    /* Floors it at 60x60. Needed as well as the clamp: the global
       img { max-width: 100% } would otherwise scale it below that inside a
       narrow container, and min-width outranks max-width. Height follows on
       its own — the asset is square — so pinning it too would only risk
       distortion if the logo were ever replaced with a different shape. */
    min-width: 60px;
    height: auto;
    border-radius: var(--radius-md);
    display: block;
}

.site-title {
    font-size: var(--text-site-title);
    line-height: 1.1;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.site-title a {
    color: var(--color-text-strong);
}

.site-title a:hover {
    color: var(--color-accent);
    text-decoration: none;
}

.site-description {
    font-size: var(--text-site-description);
    color: var(--color-text-muted);
    margin-top: 2px;
    /* Tighter than the body's 1.65, which is set for paragraphs of prose. On
       the two lines this wraps to on a narrow screen, that spacing reads as
       two separate statements rather than one phrase that happened to break.
       Left-aligned deliberately: the logo, the wordmark and both of these
       lines share a left edge, and centring would trade that away for a
       tidier right edge on lines that are already near-equal length. */
    line-height: 1.35;
}

.social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--color-text-muted);
    transition: background-color 0.2s ease, color 0.2s ease;
}

.social-link:hover {
    background-color: var(--color-surface);
    color: var(--color-accent);
}

.social-link svg {
    width: 18px;
    height: 18px;
    fill: currentColor;
}

.main-menu {
    display: flex;
    list-style: none;
    gap: var(--space-xs);
}

.main-menu a {
    display: block;
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-sm);
    color: var(--color-text-strong);
    font-weight: 500;
}

.main-menu a:hover {
    background-color: var(--color-surface);
    color: var(--color-accent);
    text-decoration: none;
}

/* ---------------------------------------------------------------
   Hero
   --------------------------------------------------------------- */

.hero {
    margin: var(--space-lg) var(--space-md);
    background-color: #000;
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.hero-cover {
    position: relative;
    min-height: clamp(240px, 34vw, 380px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
}

.hero-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: brightness(60%);
}

.hero-text {
    position: relative;
    z-index: 1;
    color: #fff;
    font-size: var(--text-hero);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.02em;
    text-align: center;
    text-wrap: balance;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
}

/* ---------------------------------------------------------------
   Next game card
   --------------------------------------------------------------- */

.next-game {
    position: relative;
    margin: 0 0 var(--space-xl);
    padding: var(--space-lg);
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.next-game-heading {
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-accent);
    font-weight: 700;
    margin-bottom: var(--space-md);
}

.next-game-details {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--space-lg);
    margin: 0;
}

.next-game-details dt {
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    margin-bottom: 2px;
}

.next-game-details dd {
    font-size: var(--text-lg);
    color: var(--color-text-strong);
    font-weight: 600;
    line-height: 1.3;
    /* Holds a line's worth of height before the value arrives, so the rows
       are already their final size at the first paint. */
    min-height: 1.3em;
}

.next-game-alerts {
    margin-bottom: var(--space-lg);
}

.next-game-alert {
    padding: var(--space-sm) var(--space-md);
    border-left: 3px solid var(--color-border);
    border-radius: var(--radius-sm);
    background-color: var(--color-bg);
    color: var(--color-text-strong);
    font-weight: 600;
}

/* An unforeseen cancellation is news; a planned skip is just information. */
.next-game-alert[data-kind="cancelled"] {
    border-left-color: var(--color-accent);
}

.next-game-alert[data-kind="skipped"] {
    color: var(--color-text-muted);
    font-weight: 500;
}

.next-game-alert + .next-game-alert {
    margin-top: var(--space-xs);
}

.next-game-cancelled-tag {
    color: var(--color-accent);
    font-size: var(--text-sm);
    font-weight: 600;
    white-space: nowrap;
}

.next-game-upcoming {
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
}

.next-game-upcoming-label {
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--space-xs);
}

/* Stacked rather than a wrapping row. Two dates then occupy two lines at every
   width, which is what makes the space below reservable — as a wrapping row the
   height changed with the viewport and could not be held in advance. */
.next-game-upcoming ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    margin: 0;
}

.next-game-upcoming li {
    color: var(--color-text-strong);
}

.next-game-subscribe {
    margin-top: var(--space-md);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.next-game-subscribe a {
    font-weight: 600;
    white-space: nowrap;
}

.next-game-note {
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    min-height: 1.65em;
}

/* Values are hidden rather than removed while loading: they keep their space,
   so nothing moves when they appear, and the reader never watches a value
   rewrite itself. visibility also takes the note's rule with it, which would
   otherwise draw a line across an empty card. */
.next-game.is-loading .next-game-details dd,
.next-game.is-loading .next-game-note,
.next-game.is-loading .next-game-upcoming,
.next-game.is-loading .next-game-subscribe {
    visibility: hidden;
}

/* Holds the room the dates and the subscribe line will need, so neither pushes
   the page down when the calendar answers. The list reserves one line per
   upcoming date, matching upcomingCount in js/calendar.js. */
.next-game.is-loading .next-game-upcoming ul {
    /* Two dates: two lines at the inherited 1.65 line-height, plus the gap
       between them. Matches upcomingCount in js/calendar.js — change both
       together. */
    min-height: calc(2 * 1.65em + var(--space-xs));
}

.next-game-subscribe {
    min-height: 1.65em;
}

/* Sits over the reserved space rather than in the flow, so showing and hiding
   it never changes the card's height. */
.next-game-loading {
    display: none;
    position: absolute;
    inset: 0;
    place-items: center;
    /* Held back a quarter second: a request that answers quickly should never
       flash a spinner, which reads as jumpier than the wait it describes. */
    opacity: 0;
    animation: next-game-loading-appear 0.2s ease 0.25s forwards;
}

.next-game.is-loading .next-game-loading {
    display: grid;
}

.next-game-loading::after {
    content: "";
    width: 26px;
    height: 26px;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: next-game-loading-spin 0.8s linear infinite;
}

@keyframes next-game-loading-appear {
    to { opacity: 1; }
}

@keyframes next-game-loading-spin {
    to { transform: rotate(360deg); }
}

/* ---------------------------------------------------------------
   Main content
   --------------------------------------------------------------- */

.site-main {
    padding: var(--space-xl) 0 var(--space-2xl);
}

.container {
    max-width: var(--width-text);
    margin-inline: auto;
    padding: 0 var(--space-md);
}

/* For content that should use the full page width, such as the photo grid. */
.container-wide {
    max-width: none;
}

.entry-title {
    font-size: var(--text-title);
    color: var(--color-text-strong);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    margin-bottom: var(--space-lg);
}

.entry-content p {
    margin-bottom: var(--space-lg);
}

.entry-content h2,
.entry-content h3 {
    color: var(--color-text-strong);
    margin: var(--space-xl) 0 var(--space-sm);
    line-height: 1.25;
}

.entry-content ul,
.entry-content ol {
    margin: 0 0 var(--space-lg) var(--space-lg);
}

.entry-content hr {
    margin: var(--space-xl) 0;
    border: 0;
    border-top: 1px solid var(--color-border);
}

.entry-content img {
    display: block;
    margin: var(--space-xl) 0;
    border-radius: var(--radius-md);
}

/* Full-width imagery reads better than prose-width imagery. */
.entry-content > p:has(> img) {
    max-width: none;
}

/* ---------------------------------------------------------------
   Photo gallery
   --------------------------------------------------------------- */

.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-md);
}

.photo-item {
    aspect-ratio: 1;
    overflow: hidden;
    border: 0;
    padding: 0;
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    cursor: zoom-in;
    display: block;
}

.photo-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.3s ease;
}

/* Zoom inside the tile: scaling the tile itself overlapped its neighbours. */
.photo-item:hover img,
.photo-item:focus-visible img {
    transform: scale(1.05);
}

/* ---------------------------------------------------------------
   Lightbox
   --------------------------------------------------------------- */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
    background-color: var(--color-overlay);
    border: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
}

.lightbox::backdrop {
    background-color: var(--color-overlay);
}

.lightbox:not([open]) {
    display: none;
}

.lightbox img {
    max-width: 100%;
    max-height: 85vh;
    object-fit: contain;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
}

.lightbox-close {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    width: 44px;
    height: 44px;
    font-size: 1.5rem;
    line-height: 1;
    color: #fff;
    background-color: rgba(255, 255, 255, 0.14);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.lightbox-close:hover {
    background-color: rgba(255, 255, 255, 0.28);
}

/* ---------------------------------------------------------------
   Footer
   --------------------------------------------------------------- */

.site-footer {
    background-color: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: var(--space-lg) var(--space-md);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

/* ---------------------------------------------------------------
   Motion
   --------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---------------------------------------------------------------
   Small screens
   --------------------------------------------------------------- */

/* Below this the header needs two rows. Claiming a full-width row for the
   actions makes that deterministic — it no longer depends on exactly where
   the wordmark happens to wrap — and, more usefully, gives the nav an edge to
   anchor against. Kept separate from the 544px block below so that the
   spacing tweaks there are not dragged to a different breakpoint. */
@media (max-width: 576px) {
    .header-actions {
        flex: 1 0 100%;
    }

    /* Social links hold the logo's left edge; the nav takes the far side, so
       the row is weighted at both ends instead of bunched to the left. */
    .header-actions nav {
        margin-left: auto;
    }
}

@media (max-width: 544px) {
    /* Branding and actions now wrap as whole units on their own, so this only
       tightens the spacing rather than dictating where the break happens. */
    .header-grid {
        gap: var(--space-xs);
    }

    .site-branding {
        gap: var(--space-sm);
    }

    .main-menu a {
        padding: var(--space-xs) var(--space-sm);
    }

    .hero {
        margin-left: 0;
        margin-right: 0;
        border-radius: 0;
    }
}
