/* Typefaces, the Monash palette and the site nav live in brand.css, which
   this page loads first. */

:root {
    /* palette */
    --abyss: #050E14;
    --deep: #0B1B26;
    --trench: #12303F;
    --current: #4E93A6;
    --mist: #8FA8B2;
    --foam: #FFFFFF;

    /* roles */
    --base-100: var(--monash-white);      /* text / light contrast */
    /* Page surface: the Monash web-accessible blue, which the Digital
       Guidelines (p.5) approve for white text overlay at WCAG AA. */
    --base-200: var(--monash-blue-aa);    /* page surface */
    --base-300: var(--monash-black);     /* deepest surface */
    --site-footer-bg: var(--abyss);       /* reveal footer ground */

    color-scheme: dark;
}

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

html,
body {
    background-color: var(--base-200);
    color: var(--base-100);
}

/* Body text, 1em desktop / 0.9375em mobile (Digital Guidelines p.3-4).
   The guidelines name Helvetica Neue for this role; brand.css serves Roboto
   instead and explains why. Display roles override this below. */
body {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: var(--type-body);
    line-height: 1.5;
}

a {
    text-decoration: none;
}

h1,
h2,
p {
    font-weight: 400;
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.preloader {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100svh;
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    background-color: var(--base-300);
    color: var(--base-100);
    will-change: clip-path;
    overflow: hidden;
    z-index: 4;
}

.preloader-header {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: max-content;
    max-width: calc(100% - 4rem);
}

/* Banner heading: Roboto Condensed Regular, 4.7em/75px desktop,
   2em/32px mobile (Digital Guidelines p.3-4). */
.preloader-header h1 {
    font-family: var(--font-banner);
    font-size: var(--type-banner-heading);
    text-transform: uppercase;
    line-height: 0.85;
}

.preloader-counter {
    position: absolute;
    top: -1.5rem;
    left: calc(100% + 1.5rem);
    overflow: hidden;
}

.preloader-counter p {
    font-family: var(--font-banner);
    font-size: var(--type-body);
    color: var(--monash-white);
    line-height: 0.85;
}

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

.outro {
    position: relative;
    z-index: 1;
    width: 100%;
    min-height: 100svh;
    padding: 6rem 0 calc(2rem + var(--cms-preview-height, 0px));
    display: flex;
    flex-direction: column;
    background-color: var(--base-300);
    color: var(--base-100);
    overflow: hidden;
}

.outro-copy {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2rem;
    max-width: 64rem;
    margin: 0 auto;
    padding: 0 2rem;
    text-align: center;
}

/* "Find a project" pill, under the hero heading and in the outro: 1em
   uppercase (Digital Guidelines p.3-4). On hover it fills white with black
   text. */
.cta {
    font-family: var(--font-body);
    font-size: var(--type-button);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--monash-white);
    padding: 0.85rem 1.75rem;
    border: 1px solid var(--monash-white);
    border-radius: 2rem;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.cta:hover,
.cta:focus-visible {
    background-color: var(--monash-white);
    color: var(--monash-black, #000);
}

/* ------------------------------------------------------------------
   Past-photos gallery: an endless tilted ribbon of cards, bent into a
   shallow curve so the ends swing towards the viewer. landing_page.js
   drifts and drags the track and writes each card's curve transform;
   the knobs it uses live there.
   ------------------------------------------------------------------ */
.gallery {
    position: relative;
    flex: 1;
    min-height: 34rem;
    perspective: 1200px;
    cursor: grab;
    user-select: none;
    /* Horizontal drags are ours; vertical ones still scroll the page. */
    touch-action: pan-y;
}

.gallery.is-dragging {
    cursor: grabbing;
}

/* Wider than the section so the tilted ends still reach its corners. */
.gallery__tilt {
    position: absolute;
    top: 50%;
    left: -25%;
    width: 150%;
    transform: translateY(-50%) rotate(12deg);
    transform-style: preserve-3d;
}

.gallery__track {
    display: flex;
    align-items: flex-start;
    transform-style: preserve-3d;
    /* JS writes translate3d here every frame. */
    will-change: transform;
}

.gallery__card {
    flex-shrink: 0;
    width: clamp(13rem, 21vw, 24rem);
    margin: 0 clamp(2rem, 5vw, 5rem) 0 0;
    will-change: transform, opacity;
}

.gallery__media {
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background-color: #111;
}

.gallery__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    -webkit-user-drag: none;
}

.gallery__card figcaption {
    margin-top: 0.75rem;
    font-family: var(--font-body);
    font-size: 0.875rem;
    letter-spacing: 0.04em;
    color: var(--monash-white);
}


/* Intro text, and the "Where ideas meet industry" section that had no rules
   of its own. */
.outro h2,
.abouttheexpo h2 {
    font-family: var(--font-banner);
    font-size: var(--type-intro-text);
    line-height: 1.35;
    color: var(--monash-white);
}

/* H2 intro heading. */
.abouttheexpo h1 {
    margin-bottom: 0.75rem;
    font-family: var(--font-heading);
    font-size: var(--type-intro-heading);
    line-height: 1.1;
    color: var(--monash-white);
}

.abouttheexpo {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 100svh;
    padding: 2rem;
    background-color: var(--base-200);
}

.aboutcontext {
    max-width: 60ch;
}

.hero {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100svh;
    background-color: var(--base-200);
    color: var(--base-100);
    overflow: hidden;
}

.hero-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Greyed and dimmed so the white heading stands out. Lower brightness
       for more contrast, raise saturate for more colour. */
    filter: brightness(0.55) saturate(0.5);
}

.frames {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100svh;
    background-color: var(--base-300);
    overflow: hidden;
}

.frames-canvas {
    display: block;
    width: 100%;
    height: 100%;
}

.cms-frame-media { width: 100%; height: 100%; object-fit: cover; }
.site-footer__copyright { padding-left: 0; }
.cms-static .frames { height: auto; padding: 3rem 8%; }
.cms-static .frames-canvas { position: relative; height: 60vh; }
.cms-static canvas.frames-canvas { display: none; }
/* Without animations, show the laptop's first stop as a still (the second,
   frame 228, is all black: the camera is inside the screen by then). */
.cms-static .frames::before { content: ''; display: block; height: 60vh; background: url('../img/landing/scrolltriggeranim/0150.webp') center/cover; }
.cms-static .frames:has(.cms-frame-media)::before { display: none; }
.cms-static .frames-about { position: relative; opacity: 1; visibility: visible; padding: 2rem 0 0; }

/* "About the Expo", over the open laptop: the title steps down to the right
   on the left of the lid; the copy is a tall, narrow column on the right.
   Both sit in the middle of the screen's height. Hidden until
   landing_page.js adds .is-visible while the scroll rests on the open
   laptop, then faded in and out.

   The section is exactly one screen tall and clips, so the type scales with
   whichever of the screen's width or height is tighter: large on a big
   screen, never spilling out of the box on a small one. */
.frames-about {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: grid;
    grid-template-columns: 50% 1fr;
    align-items: center;
    gap: 2rem 4%;
    padding: clamp(4.5rem, 11vh, 7rem) 5rem 3rem 2.5rem;
    color: var(--monash-white);
    font-family: var(--font-body);
    font-size: clamp(1rem, min(1.9vw, 3.1vh), 2.25rem);
    font-weight: 700;
    line-height: 1.6;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.6s ease, visibility 0.6s;
    pointer-events: none;
}

.frames-about.is-visible {
    opacity: 1;
    visibility: visible;
}

/* The overlay's empty space stays click-through; the words themselves can
   be selected and copied once shown. */
.frames-about.is-visible > * {
    pointer-events: auto;
}

/* ABOUT / THE / EXPO. in the site's condensed face, set solid: the line
   height is the capitals' own height, so each word's base meets the top of
   the next, and each word steps further right. --stretch pulls the letters
   taller for the narrow poster look, about the middle so the title stays
   centred. */
.frames-about__title {
    --stretch: 1.2;
    font-family: var(--font-banner);
    font-size: clamp(3rem, min(10.5vw, 25vh), 14rem);
    line-height: 0.72;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    transform: scaleY(var(--stretch));
    transform-origin: left center;
}

.frames-about__title span {
    display: block;
    /* A word never breaks, or "EXPO." would lose its full stop to a new line. */
    white-space: nowrap;
}

.frames-about__title span:nth-child(2) { padding-left: 1.17em; } /* its H sits over the E of EXPO */
.frames-about__title span:nth-child(3) { padding-left: 1.7em; }

/* Narrow and centred, so the copy runs down more than across. */
.frames-about__body {
    text-align: center;
}

/* The two paragraphs a step smaller than the statement's base size, but
   never below a readable size on a phone, and narrow so they run down.
   Left-aligned on the column's left edge; the statement stays centred. */
.frames-about__body p {
    max-width: 21em;
    font-size: max(0.85em, 0.875rem);
    text-align: left;
}

/* Side by side, the copy's first line starts level with the top of the T
   in ABOUT: both columns sit at the top of the (vertically centred) row,
   the title stretches downwards from its top, and the first paragraph is
   pulled up by the gap between its line top and its capitals. */
@media (min-width: 901px) {
    .frames-about {
        align-items: start;
        align-content: center;
    }

    .frames-about__title {
        transform-origin: left top;
    }

    .frames-about__body p:first-child {
        margin-top: -0.26em;
    }
}

/* The site's base styles reset headings and paragraphs to regular weight. */
.frames-about__title,
.frames-about p {
    font-weight: 700;
}

.frames-about p + p {
    margin-top: 1.5em;
}

/* The big statement between the paragraphs, set like ruitat.info's "Art
   that leaves the room with you.": light and tightly tracked, with the
   quoted phrase in a serif. It spans the whole right column, wider than
   the copy around it but never reaching the title. */
.frames-about .frames-about__statement {
    max-width: none;
    margin: 0.6em 0;
    text-align: center;
    font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
    font-size: 2em;
    font-weight: 300;
    line-height: 1.01;
    letter-spacing: -0.06em;
}

.frames-about__statement em {
    font-family: Georgia, "Times New Roman", serif;
    font-style: normal;
    font-weight: 400;
    letter-spacing: -0.065em;
}

/* Narrow screens: the title across the top, centred, and the copy below,
   all sized to fit one screen. */
@media (max-width: 900px) {
    .frames-about {
        grid-template-columns: 1fr;
        grid-template-rows: auto 1fr;
        align-items: start;
        gap: 1.5em;
        padding: 5.5rem 2.5rem 1.5rem 2.5rem;
        font-size: clamp(0.875rem, min(3.9vw, 2.3vh), 1.25rem);
    }

    .frames-about__title {
        font-size: 3.2em;
        text-align: center;
        transform-origin: center top;
        /* Stretching grows it down, so leave that room below. */
        margin-bottom: calc((var(--stretch) - 1) * 0.72em);
    }

    /* Still one word per line, but centred rather than stepped. */
    .frames-about__title span:nth-child(n) { padding-left: 0; }

    .frames-about__body { align-self: center; }
    .frames-about p + p { margin-top: 1em; }
    .frames-about .frames-about__statement { margin: 0.4em 0; }
}

/* Progress dots, built by initFrames() from the snap labels. Sizes are
   variables so the phone layout below only has to change these. */
.frames-dots {
    --dot-hit: 1.25rem;     /* button size, the click/tap area */
    --dot-size: 0.375rem;   /* idle dot */
    --dot-active: 1.25rem;  /* current stop */
    --dot-gap: 0.75rem;     /* dotted line between stops */

    position: absolute;
    top: 50%;
    right: 2rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    list-style: none;
    transform: translateY(-50%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s;
}

.frames-dots.is-active {
    opacity: 1;
    pointer-events: auto;
}

.frames-dots li {
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Dotted line from the stop above. */
.frames-dots li + li::before {
    content: "";
    height: var(--dot-gap);
    margin: 0.25rem 0;
    border-left: 2px dotted var(--mist);
}

.frames-dots button {
    display: grid;
    place-items: center;
    width: var(--dot-hit);
    height: var(--dot-hit);
    border: 0;
    background: none;
    cursor: pointer;
}

.frames-dots button::after {
    content: "";
    width: var(--dot-size);
    height: var(--dot-size);
    border-radius: 50%;
    background: var(--mist);
    transition: width 0.3s, height 0.3s;
}

/* Current stop: a white ring around a dark centre. */
.frames-dots button[aria-current="step"]::after {
    width: var(--dot-active);
    height: var(--dot-active);
    background: radial-gradient(circle, var(--base-300) 0 20%, var(--monash-white) 24%);
}

.frames-dots button:focus-visible {
    outline: 2px solid var(--monash-white);
    outline-offset: 2px;
    border-radius: 50%;
}

@media (max-width: 768px) {
    .frames-dots {
        --dot-hit: 1rem;
        --dot-size: 0.3rem;
        --dot-active: 1rem;
        --dot-gap: 0.4rem;
        right: 0.75rem;
    }
}


.header {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2rem;
    transform: translate(-50%, -50%);
    width: 100%;
    height: max-content;
    /* Room for the button's focus outline inside the overflow clip. */
    padding-bottom: 4px;
    overflow: hidden;
}

/* Down arrow to the footer: fixed bottom right instead until the footer showing
   (landing_page.js adds .is-hidden). */
.hero-fab {
    position: fixed;
    right: 1.5rem;
    bottom: calc(1.5rem + var(--cms-preview-height, 0px));
    z-index: 3;
    display: grid;
    place-items: center;
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-radius: 50%;
    color: var(--monash-white);
    background-color: rgba(0, 0, 0, 0.35);
    cursor: pointer;
    transition: background-color 0.2s, transform 0.3s ease, opacity 0.3s ease;
}

/* Lifted above countdown strip while showing (it is gone once the expo ends). */
.expo-strip:not([data-state="after"]) ~ .hero-fab {
    bottom: calc(40px + 1rem + var(--cms-preview-height, 0px));
}

.hero-fab.is-hidden {
    transform: translateY(1rem);
    opacity: 0;
    pointer-events: none;
}

@media (max-width: 600px) {
    .hero-fab { right: 1rem; width: 3rem; height: 3rem; }
}

/* Touch screens keep :hover after a tap, so only mice get it. */
@media (hover: hover) {
    .hero-fab:hover {
        background-color: rgba(0, 0, 0, 0.6);
    }
}

.hero-fab:focus-visible {
    outline: 2px solid var(--monash-white);
    outline-offset: 3px;
}

.hero-fab svg {
    width: 1.5rem;
    height: 1.5rem;
}

/* Banner heading, at twice the brand banner size. */
.header h1 {
    font-family: var(--font-banner);
    font-size: calc(var(--type-banner-heading) * 2);
    text-transform: uppercase;
    line-height: 0.9;
}

/* Accents and other scripts rise above Latin capitals; give them room inside the masks. */
html:not([lang="en"]) .preloader-header h1,
html:not([lang="en"]) .header h1 {
    line-height: 1.2;
}

.hero-footer {
    position: absolute;
    width: 100%;
    bottom: 0;
    padding: 2rem;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
}

.preloader-counter p {
    transform: translateY(100%);
    will-change: transform;
}

.preloader-header h1,
.header h1,
.nav-links a,
.nav-lang summary,
.nav-brand,
.nav-toggle,
.hero-footer p {
    visibility: hidden;
}

/* Intro already seen this visit: no overlay, and the copy the preloader
   would have animated in is simply present. These elements are hidden
   above only because the timeline reveals them. */
.intro-seen .preloader {
    display: none;
}

.intro-seen .preloader-header h1,
.intro-seen .header h1,
.intro-seen .nav-links a,
.intro-seen .nav-lang summary,
.intro-seen .nav-brand,
.intro-seen .nav-toggle,
.intro-seen .hero-footer p {
    visibility: visible;
}

@media (max-width: 1000px) {
    .preloader-counter {
        top: -1.5rem;
        left: calc(100% + 0.5rem);
    }
}

@media (max-width: 767px) {
}

@media (max-height: 500px) {
    .header h1 { font-size: 4rem; }
}


/* ==================================================================
   THE YEAR IN NUMBERS
   Over the laptop's black stop and the stops after it: the chart on the
   right, the current step's number on the left, both faded in by
   landing_page.js. 
   Mobile: chart on top, the step along the bottom.
   ================================================================== */
.frames-stats {
    position: absolute;
    inset: 0;
    z-index: 1;
    color: var(--monash-white);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.6s ease, visibility 0.6s;
    pointer-events: none;
}

.frames-stats.is-visible {
    opacity: 1;
    visibility: visible;
}

.frames-stats__chart {
    position: absolute;
    inset: max(14vh, 6rem) 5vw 8vh 46%;
}

.frames-stats.is-visible .frames-stats__chart {
    pointer-events: auto;
}

.frames-stats__step {
    position: absolute;
    top: 50%;
    left: 2.5rem;
    width: 40%;
    opacity: 0;
    visibility: hidden;
    transform: translateY(calc(-50% + 2rem));
    transition: opacity 0.5s ease, transform 0.5s ease, visibility 0.5s;
}

.frames-stats__step.is-active {
    opacity: 1;
    visibility: visible;
    transform: translateY(-50%);
    pointer-events: auto;
}

.frames-stats__heading,
.frames-stats__number {
    font-family: var(--font-banner);
    font-weight: 700;
    text-transform: uppercase;
    line-height: 0.9;
}

.frames-stats__heading { font-size: clamp(1.75rem, min(4vw, 7vh), 4.5rem); }

.frames-stats__number {
    font-size: clamp(4.5rem, min(13vw, 22vh), 12rem);
}

/* The first step carries the heading and intro too, so its number is
   smaller to leave them room. */
.frames-stats__heading + .frames-stats__number {
    margin-top: 1.25rem;
    font-size: clamp(3rem, min(9vw, 14vh), 8rem);
}

.frames-stats__label {
    margin-top: 0.75rem;
    font-size: clamp(1.125rem, 2vw, 1.75rem);
    font-weight: 700;
    text-transform: uppercase;
}

.frames-stats__intro {
    max-width: 32em;
    margin-top: 1.5rem;
    font-size: clamp(0.875rem, min(1.3vw, 2.2vh), 1.25rem);
    line-height: 1.55;
}

/* The longer copy under a number: paragraphs, and bullet lists whose
   lead-in line is bold. */
.frames-stats__text {
    max-width: 34em;
    margin-top: 1.25rem;
    font-size: clamp(0.875rem, min(1.2vw, 2.1vh), 1.125rem);
    line-height: 1.5;
}

.frames-stats__text p + p,
.frames-stats__text ul + p { margin-top: 0.75em; }
.frames-stats__text p:has(+ ul) { font-weight: 700; }

.frames-stats__text ul {
    margin-top: 0.35em;
    padding-left: 1.2em;
    list-style: disc;
}

.frames-stats__text ul:has(li:nth-child(5)) {
    columns: 2;
    column-gap: 2em;
}

.frames-stats__text li { break-inside: avoid; }

/* Room for the copy: text has a smaller number. */
.frames-stats__step:has(.frames-stats__text) .frames-stats__number {
    font-size: clamp(3rem, min(9vw, 14vh), 8rem);
}

.frames-stats__list {
    margin-top: 1.5rem;
    list-style: none;
    font-size: 1.25rem;
    line-height: 1.8;
}

/* The list stands in until ECharts has drawn donut. */
.frames-stats.has-chart .frames-stats__list { display: none; }

/* Without the scroll animation: every step in turn. */
.cms-static .frames-stats {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 3rem;
    padding: 3rem 0 0;
    opacity: 1;
    visibility: visible;
}

.cms-static .frames-stats__step {
    position: static;
    width: auto;
    opacity: 1;
    visibility: visible;
    transform: none;
}

.cms-static .frames-stats__chart {
    position: relative;
    inset: auto;
    order: 1;
    height: 60vh;
}

.cms-static .frames-stats__chart:empty { display: none; }

@media (max-width: 900px) {
    /* Clear of the step below and the stop dots on the right. */
    .frames-stats__chart { inset: 12svh 2.5rem 51svh 1rem; }

    .frames-stats__step {
        top: auto;
        right: 1.5rem;
        /* Clear of the fixed log-in button. */
        bottom: calc(6svh + 4rem);
        left: 1.5rem;
        width: auto;
        transform: translateY(2rem);
    }

    .frames-stats__step.is-active { transform: none; }
    .frames-stats__number { font-size: 4.5rem; }
    .frames-stats__heading + .frames-stats__number { margin-top: 0.75rem; }
    .frames-stats__intro { margin-top: 0.75rem; font-size: 0.9rem; line-height: 1.5; }
}
/* Lenis drives the scroll and the frames section has its own progress dots. 
   The scroll hold (landing_page.js) pauses
   Lenis, clipping the page scrollbar would vanish and return each time,
   shifting the whole page sideways by width. */
html {
    scrollbar-width: none;
}

html::-webkit-scrollbar {
    display: none;
}

/* The nav turns solid from the last chart step to the end of the outro
   (landing_page.js), text and photos pass under it. */
.site-nav--fixed {
    transition: background-color 0.3s ease;
}

.site-nav--fixed.is-solid {
    background-color: var(--base-300);
}

/* Countdown to the booths opening, between the outro text and button.
   Only "before" shows the timer; open, ended and TBA show just the date. */
.outro-countdown {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
}

.outro-countdown__label {
    font-family: var(--font-body);
    font-size: var(--type-button);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.8;
}

.outro-countdown__time {
    font-family: var(--font-banner);
    font-size: var(--type-banner-subtext);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.outro-countdown__when {
    font-family: var(--font-body);
    font-size: var(--type-body);
    opacity: 0.8;
}

.outro-countdown:not([data-state="before"]) :is(.outro-countdown__label, .outro-countdown__time) {
    display: none;
}

/* The outro button reads "Find a project"; hovering or focusing it swaps in
   whether the booths are open,
   button keeps the width of the longer and never jumps. */
.cta--status {
    display: inline-grid;
    justify-items: center;
}

.cta--status > span {
    grid-area: 1 / 1;
    transition: opacity 0.2s ease;
}

.cta__status,
.cta--status:is(:hover, :focus-visible):has(.cta__status) .cta__label {
    opacity: 0;
}

.cta--status:is(:hover, :focus-visible) .cta__status {
    opacity: 1;
}

/* Expo date and countdown, fixed along bottom of screen. */
.expo-strip {
    position: fixed;
    inset: auto 0 0;
    z-index: 3;
    display: flex;
    /* Countdown on the left, date on the right. */
    flex-direction: row-reverse;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    /* As tall as the DebugKit icon. */
    height: 40px;
    padding: 0 2rem;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    background-color: rgb(0 109 174 / 0.6);
    backdrop-filter: blur(8px);
    color: var(--monash-white);
    font-family: var(--font-banner);
    font-size: 0.875rem;
    line-height: 1.3;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    transition: transform 0.3s ease, opacity 0.3s ease;
}

.expo-strip.is-hidden {
    transform: translateY(100%);
    opacity: 0;
    pointer-events: none;
}

.expo-strip__when { opacity: 0.85; }

.expo-strip [data-countdown-time] { margin-left: 0.5em; }

/* A live dot when booths are open. */
.expo-strip__open::before {
    content: "";
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    margin-right: 0.6em;
    border-radius: 50%;
    background-color: #2ecc71;
    vertical-align: 0.1em;
    animation: expo-strip-pulse 1.6s ease-in-out infinite;
}

@keyframes expo-strip-pulse {
    50% { opacity: 0.3; }
}

.expo-strip:not([data-state="before"]) .expo-strip__before,
.expo-strip:not([data-state="open"]) .expo-strip__open,
.expo-strip[data-state="after"] {
    display: none;
}

@media (max-width: 600px) {
    .expo-strip { justify-content: center; padding-inline: 1rem; }
    .expo-strip__when { display: none; }
}

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

/* "The expo is still closed", tucked under Find a project button. */
.cta-note {
    margin-top: -1rem;
    font-family: var(--font-body);
    font-size: var(--type-body);
    opacity: 0.85;
}
