/*
 * Have Your Say hub page.
 *
 * Wrapped in `@layer app` to match custom.css's cascade-layer convention:
 * app beats theme/base/components and loses to utilities.
 *
 * THE SLIDE MODEL — read this before changing anything below.
 *
 * Each section is one "slide": exactly the height of the viewport minus the
 * two sticky bars above it, never taller (no scrolling inside a slide) and
 * never shorter (no dead white gap under it).
 *
 * Getting that right needs three things together, and the earlier version of
 * this file only did the first, which is why every slide had a white band
 * under it:
 *
 *   1. the section is given that exact height, AND
 *   2. the section is a flex column so its child can be told to fill it, AND
 *   3. the section carries the slide's background colour itself.
 *
 * (3) matters as much as (1): the shared survey/quiz templates paint their
 * own background on an inner div. If the section behind them is transparent,
 * any height the inner div doesn't use shows through as a white stripe. So
 * every slide sets its background on the SECTION and the inner component
 * stretches to cover it.
 */
@layer app {

/*
 * The sticky jump nav sits below the site header, whose height differs
 * between the desktop and mobile header markup — there's no single CSS
 * constant for it. have-your-say.js measures #masthead on load/resize and
 * writes the real value here; these are safe fallbacks for the instant
 * before that runs. --hys-nav-h is the jump nav's own height.
 */
:root {
    --hys-header-h: 60px;
    --hys-nav-h: 55px;
    --hys-slide-h: calc(100svh - var(--hys-header-h) - var(--hys-nav-h));
}

/*
 * Tailwind v4 strips the unprefixed `backdrop-filter` (same note as the top
 * of custom.css) — Safari needs the -webkit- one too, or `backdrop-blur-*`
 * renders unblurred there.
 */
.hys-nav {
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

/* Scrollbar hiding on the horizontal pill rails — two vendor properties
 * working together, not a single Tailwind utility. */
.hys-scroll-x {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.hys-scroll-x::-webkit-scrollbar {
    display: none;
}

/* ------------------------------------------------------------------ *
 * 1 + 2 · Slide sizing
 * ------------------------------------------------------------------ */
.hys-section {
    position: relative;
    height: var(--hys-slide-h);
    min-height: var(--hys-slide-h);
    scroll-margin-top: calc(var(--hys-header-h) + var(--hys-nav-h));
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* The component the slide wraps fills it. Without this the component sits at
 * its natural height at the top of the slide and the rest shows through. */
.hys-section > * {
    flex: 1 1 auto;
    min-height: 0;
}

/* ------------------------------------------------------------------ *
 * 3 · Slide backgrounds — on the section, matching the inner component
 * ------------------------------------------------------------------ */
/* --hys-fade feeds the survey photo's edge-fade (below): each slide fades the
 * photo into ITS OWN background instead of a hardcoded black, so the fade
 * never mismatches a tan or paper slide. */
.hys-section--dark  { background-color: #000; --hys-fade: #000; }
.hys-section--tan   { background-color: #d4c4a8; --hys-fade: #d4c4a8; }
.hys-section--paper { background-color: #fff; --hys-fade: #fff; }

/* ------------------------------------------------------------------ *
 * Share button — same place on every slide, instead of wherever each
 * component happened to put it (floated in a heading, inline after a
 * title, absolutely nowhere consistent).
 *
 * !important on the two background-color declarations below: every button
 * on this page carries marketing.css's `.share-anchor-btn-light` class (it
 * was designed for the homepage, where every slide is a dark photo), and
 * that file is NOT wrapped in `@layer app` — so its unlayered rule beats
 * this file's layered one on background-color regardless of specificity.
 * That was invisible on the dark/photo slides (a translucent-white chip
 * still reads against dark art) but made the State Challenge slide's share
 * button a literal white-on-white ghost, since #hys-states is the paper
 * (#fff) background. !important is the only way a layered rule out-ranks
 * an unlayered one, short of moving marketing.css into a layer itself.
 * ------------------------------------------------------------------ */
.hys-section .share-anchor-btn {
    position: absolute;
    top: 14px;
    right: 18px;
    z-index: 20;
    float: none;
    margin: 0;
    width: 34px;
    height: 34px;
    font-size: 14px;
    line-height: 1;
    border-radius: 50%;
    background-color: rgb(0 0 0 / 0.28) !important;
    color: #fff;
    opacity: 1;
    transition: background-color 0.2s ease;
}
.hys-section .share-anchor-btn:hover {
    background-color: rgb(0 0 0 / 0.55) !important;
}
/* On the light slides a translucent-black chip has enough contrast, but the
 * icon needs to stay legible when it lands over pale photography. */
.hys-section--tan .share-anchor-btn,
.hys-section--paper .share-anchor-btn {
    background-color: rgb(0 0 0 / 0.35) !important;
}

/* ------------------------------------------------------------------ *
 * Jump-nav pills
 *
 * Colours live here, not as utilities in the markup: the active state is
 * toggled from JS, and an arbitrary utility like `bg-[#1a1a1a]` only reaches
 * the bundle if Tailwind's scanner catches the literal, then still loses to
 * the pill's own `bg-white` because `app` sits below `utilities`.
 * ------------------------------------------------------------------ */
.hys-pill {
    background-color: #fff;
    border-color: rgb(0 0 0 / 0.1);
    color: #5c5750;
}
.hys-pill:hover {
    border-color: rgb(0 0 0 / 0.2);
    color: #000;
}
.hys-pill.is-active,
.hys-pill.is-active:hover {
    background-color: #1a1a1a;
    border-color: #1a1a1a;
    color: #fff;
}

/* ------------------------------------------------------------------ *
 * 01 / 04 / 05-08 · Survey slides
 *
 * survey.php is shared and can't be edited for this page alone, so its
 * layout is stretched from here. !important is required where it fights a
 * Tailwind utility baked into that markup — utilities sit in a layer above
 * `app`, so specificity alone can never win.
 * ------------------------------------------------------------------ */
.hys-section .homepage-survey-container {
    display: flex;
    height: 100%;
}
.hys-section .homepage-survey-inner {
    flex: 1;
    width: 100%;
    max-height: none !important;
}
/* custom.css's photo edge-fade (.homepage-survey-photo::after) always fades to
 * #000 because on the homepage the photo sits beside a black panel. Here the
 * panel is the slide's own background — tan or paper on some slides — so a
 * hardcoded black fade reads as a smudge. Route it through --hys-fade (set
 * per .hys-section--dark/--tan/--paper above) instead. Higher specificity
 * than the unscoped rule wins outright, no !important needed, and it only
 * touches slides carrying .hys-section — the homepage's own copy is untouched. */
.hys-section .homepage-survey-photo::after {
    background: linear-gradient(to bottom, transparent 92%, var(--hys-fade, #000));
}
/* The photo half fills the slide instead of holding a square aspect box.
 * (aspect-ratio needs no !important: custom.css's own md+ rule already sets
 * the same `auto`, so there's nothing here to out-rank.) */
@media (min-width: 768px) {
    .hys-section .homepage-survey-photo {
        aspect-ratio: auto;
        height: 100%;
    }
    .hys-section .homepage-survey-photo::after {
        background: linear-gradient(to right, transparent 94%, var(--hys-fade, #000));
    }
    /* survey.php pins the title to the top of row 1 and the form to the bottom
     * of row 2, which is right at its original height. Stretched to a full
     * slide that leaves a canyon between them, so pull the pair together and
     * let the whitespace fall above and below instead. Each align-self beats
     * the template's own `md:self-start` / `md:self-end`; the panel's
     * padding-top beats its `md:pt-0`. */
    .hys-section .homepage-survey-title {
        align-self: end !important;
        padding-bottom: 0;
    }
    .hys-section .homepage-survey-panel {
        align-self: start !important;
        padding-top: clamp(1.25rem, 3vw, 2.5rem) !important;
    }
}
/* Admin-only convenience link — never part of the slide's height budget. */
.hys-section .homepage-survey-container ~ .bg-blue-50 {
    position: absolute;
    left: 50%;
    bottom: 8px;
    transform: translateX(-50%);
    margin: 0 !important;
    padding: 0.4rem 1rem !important;
    z-index: 15;
}

/* ================================================================== *
 * 01b · Community answers — the third region on a survey slide
 *
 * A survey slide used to be two regions: photo, and a rail holding the
 * headline over the form. It is now three: photo | rail | drawer, where the
 * rail also carries a micro list of what other people answered and the
 * drawer holds all of them. That is the same grid the Caption Challenge
 * uses, deliberately — eight slides on this page, two of which were
 * different products, now read as one.
 *
 * The bill for the third region is paid by the headline: Hackney comes down
 * from ~82px to ~36px. That was the accepted trade. Everything below that
 * shrinks a notch with it, because the rail is 400px and a 7.5em label plus
 * a 16px input does not fit in 400px.
 *
 * This markup only exists when SurveyPresenter is asked for it
 * (render_survey($slug, true)), which is this page and nowhere else — the
 * homepage still gets the two-region composition the client approved. So
 * these rules can be blunt: there is no other page for them to leak onto.
 * ------------------------------------------------------------------ */

/* Per-slide tokens. The survey slides come in three background colours and
 * every ink/line/surface below is derived from that, rather than each rule
 * carrying its own dark-mode twin. */
.hys-section--dark {
    --sv-fg: #fff;
    --sv-dim: rgb(255 255 255 / 0.62);
    --sv-rank: rgb(255 255 255 / 0.42);
    --sv-line: rgb(255 255 255 / 0.15);
    --sv-surf: rgb(255 255 255 / 0.12);
    --sv-accent: #7fd6b0;
}
.hys-section--tan,
.hys-section--paper {
    --sv-fg: #333;
    --sv-dim: #6a6055;
    --sv-rank: #8d8271;
    --sv-line: rgb(0 0 0 / 0.13);
    --sv-surf: rgb(255 255 255 / 0.72);
    --sv-accent: var(--color-rov-green);
}

/* ---- the photograph: contained, never cropped ---------------------- *
 * custom.css covers the photo, because on the homepage it fills a half of
 * the slide edge to edge and a crop is the point. Here it is a picture of a
 * specific bridge/diner/museum that people are being asked about, and
 * cover was quietly guillotining the subject at some viewport widths.
 * Contain letterboxes it onto the slide's own background colour instead —
 * matching what the Caption Challenge already does with its photo
 * (.cc-shot img{object-fit:contain}), so the two slide types agree.
 *
 * Higher specificity than custom.css's own `.homepage-survey-photo`, both
 * in `app`, so no !important is needed. The inline background-image from
 * the registry is untouched (inline beats any sheet), and the homepage's
 * own rendering is untouched because nothing there carries .hys-section.
 *
 * The edge fade goes with it. That gradient existed to soften where a bled
 * photo was CUT by the panel; a contained photo has no cut edge — it ends
 * in the slide's own colour already — so the fade was just a smudge laid
 * over the picture's own bottom/right edge. Removed rather than retuned. */
.hys-section .homepage-survey-photo {
    background-size: contain;
    background-position: center center;
}
.hys-section .homepage-survey-photo::after {
    background: none;
}

/* The photo is a close target while the drawer is open (the document-level
 * outside-click handler in survey-submissions.js already closes on it), but
 * nothing said so — the Caption Challenge teaches that gesture with a pill
 * and these slides didn't, so the same affordance had to be learned twice.
 * The fade's ::after is free now that the gradient is gone, so it carries the
 * label rather than adding an element to markup shared with the homepage.
 * Below 1000px the drawer is a near-full-width overlay and there is no photo
 * left to click, so the pill is desktop-only — same rule .cc follows. */
@media (min-width: 1000px) {
    .hys-section .survey-shell.is-subs-open .homepage-survey-photo {
        cursor: zoom-out;
    }
    .hys-section .survey-shell.is-subs-open .homepage-survey-photo::after {
        content: "Click to close";
        position: absolute;
        left: 50%;
        bottom: 14px;
        transform: translateX(-50%);
        inset: auto auto 14px 50%;
        font-size: 10px;
        font-weight: 800;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: #fff;
        background: rgb(0 0 0 / 0.38);
        padding: 5px 10px;
        border-radius: 20px;
        white-space: nowrap;
    }
}

/* ---- the shell + the drawer mechanic ------------------------------- *
 * Same principle as .cc, and for the same reason: the shell is wider than
 * the slide by exactly one drawer, so the drawer is laid out at its final
 * width from first paint and parked off the right edge. Opening sets the
 * shell to 100% and the photo yields. The drawer itself never re-lays out —
 * animating ITS width instead reflows every card inside it mid-transition,
 * which reads as the panel being built on click rather than arriving. */
/* Section 01 makes the container a flex row and the shell `flex: 1`, which is
 * flex-basis:0 — and a flex-basis silently outranks any width you set on the
 * item. The shell's whole mechanic IS its width, so on these slides the
 * container goes back to being a block and the shell takes the height
 * directly. (Cost an hour: the drawer sat visible inside the slide and every
 * width in the devtools read exactly as authored.) */
.hys-section .homepage-survey-container.survey-has-subs {
    display: block;
}
.hys-section .survey-shell {
    height: 100%;
    /* The shell is deliberately wider than the slide, so it must not be the
     * containing block for anything absolute: the share button is pinned to
     * `right:18px` and was landing 560px off the right edge, inside the parked
     * drawer. Static hands that job back to .homepage-survey-container, which
     * is the slide's real width. */
    position: static !important;
}

@media (min-width: 1000px) {
    .hys-section .survey-shell {
        --sv-rail: clamp(340px, 27vw, 420px);
        --sv-drawer: min(44vw, 560px);
        /* !important on the three grid properties and on max-width/margin:
         * they fight `md:grid-cols-2`, `md:grid-rows-[1fr_1fr]`,
         * `max-w-[1400px]` and `mx-auto` — utilities, which sit in a layer
         * above `app`, so specificity alone can never win. mx-auto is the
         * dangerous one: with the shell deliberately wider than its
         * container, auto margins would centre the overflow and hang the
         * photo off the LEFT edge as well as the right. */
        display: grid !important;
        grid-template-columns: minmax(0, 1fr) var(--sv-rail) var(--sv-drawer) !important;
        grid-template-rows: minmax(0, 1fr) !important;
        width: calc(100% + var(--sv-drawer));
        max-width: none !important;
        margin-inline: 0 !important;
        transition: width 0.45s cubic-bezier(0.4, 0, 0.2, 1);
    }
    .hys-section .survey-shell.is-subs-open {
        width: 100%;
    }
    /* The photo carries `md:row-span-2` from the two-row homepage grid; left
     * alone in a one-row grid it would conjure a second row and halve the
     * slide. Pinned explicitly instead. */
    .hys-section .survey-shell .homepage-survey-photo {
        grid-area: 1 / 1 / 2 / 2 !important;
        height: auto;
    }
    .hys-section .survey-shell .survey-rail {
        grid-area: 1 / 2 / 2 / 3;
    }
    .hys-section .survey-shell .survey-drawer {
        grid-area: 1 / 3 / 2 / 4;
    }
}

/* ---- the rail ------------------------------------------------------ */
.hys-section .survey-rail {
    display: flex;
    flex-direction: column;
    min-height: 0;
    z-index: 3;
    /* --hys-fade is the slide's own background colour (set per
     * .hys-section--dark/--tan/--paper above). The rail must be opaque or
     * its shadow falls on nothing. */
    background: var(--hys-fade, #000);
    padding: clamp(18px, 2vw, 28px) clamp(16px, 1.9vw, 28px) clamp(16px, 1.7vw, 24px);
    box-shadow: -14px 0 30px rgb(0 0 0 / 0.14);
}

/* Every rule in this block exists to out-rank a utility baked into
 * survey.php's markup — the type scale, the paddings and the two
 * align-selfs from section 01 above. The align-selfs are not cosmetic: in
 * the homepage's GRID they mean "pull the title and form together
 * vertically", but the rail is a flex COLUMN, where align-self is the
 * HORIZONTAL axis — left as-is they shove the headline to the right edge
 * and the form to the left. */
.hys-section .survey-rail .homepage-survey-title {
    align-self: stretch !important;
    flex: 0 0 auto;
    text-align: left !important;
    padding: 0 !important;
    margin: 0 0 0.35rem !important;
    font-size: clamp(1.35rem, 2.5vw, 2.25rem) !important;
    line-height: 0.95;
}
.hys-section .survey-rail .homepage-survey-panel {
    align-self: stretch !important;
    flex: 0 0 auto;
    padding: 0 !important;
}
.hys-section .survey-rail .homepage-survey-subtitle {
    text-align: left !important;
    font-size: 1rem !important;
    margin-bottom: 0.6rem !important;
}
.hys-section .survey-rail .homepage-survey-input-row {
    margin-bottom: 0.5rem !important;
    gap: 0.6rem;
}
/* 7.4em, not the template's 7.5em-at-20px: the labels are nowrap, so the box
 * has to clear the longest one any campaign registers ("Museum Name") or it
 * runs under its own input. */
.hys-section .survey-rail .homepage-survey-label {
    font-size: 0.82rem !important;
    width: 7.4em !important;
}
.hys-section .survey-rail .homepage-survey-input {
    padding: 0.35rem 0.6rem !important;
    font-size: 0.875rem !important;
}
/* `.justify-end` is the submit row's only unique hook — the field rows are
 * `.flex` too, so a child selector on `.flex` would hit all of them. */
.hys-section .survey-rail form > .justify-end {
    margin-top: 0.6rem !important;
}
.hys-section .survey-rail .homepage-survey-submit {
    padding: 0.45rem 1.25rem;
    font-size: 0.82rem;
}

/* Both the slide's share chip and the drawer's close button want the top
 * right corner, and with the drawer open they land on top of each other —
 * on the Caption Challenge the × was literally sitting under the share icon.
 * The close button wins: while the drawer is open it is the only control
 * that gets you out of it, whereas the share link is still one Escape away
 * from being available again. Both slide types, so the rule is learned once. */
.hys-section .survey-shell.is-subs-open .share-anchor-btn,
.hys-section .cc.cc-showAll .share-anchor-btn {
    opacity: 0;
    pointer-events: none;
}

/* ---- micro list: the foot of the rail ------------------------------ */
.survey-micro {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    margin-top: clamp(12px, 1.6vw, 22px);
    font-family: "Gotham Book", sans-serif;
}
.survey-micro-head {
    flex: 0 0 auto;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--sv-dim);
    padding-bottom: 7px;
    border-bottom: 1px solid var(--sv-line);
    margin-bottom: 4px;
}
.survey-micro-head b {
    color: var(--sv-fg);
}
.survey-micro-all {
    font: 700 11px/1 "Gotham Book", sans-serif;
    letter-spacing: 0;
    text-transform: none;
    color: var(--sv-accent);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    white-space: nowrap;
}
.survey-micro-all:hover {
    text-decoration: underline;
}
/* The list is clipped, not scrolled: a scrollbar inside a slide that itself
 * can't scroll invites a wheel gesture that fights the page. The mask is the
 * "there is more" cue, and the See-all button is how you get to it. */
.survey-micro-list {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
}
/* Nothing is being clipped, so a fade would be a lie about there being more.
 * It also stops growing: two answers with a stretched list puts the footer
 * line at the foot of the rail with a screen of nothing between, which reads
 * as rows that failed to load rather than a campaign that just started. */
.survey-micro-list.is-complete {
    flex: 0 0 auto;
    mask-image: none;
    -webkit-mask-image: none;
}
.survey-micro-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 2px;
    border-bottom: 1px solid var(--sv-line);
}
.survey-micro-rank {
    flex: 0 0 18px;
    font: 700 11px/1 "Gotham Book", sans-serif;
    color: var(--sv-rank);
    text-align: right;
}
.survey-micro-body {
    flex: 1 1 auto;
    min-width: 0;
}
.survey-micro-name {
    display: block;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--sv-fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.survey-micro-place {
    display: block;
    font-size: 11px;
    line-height: 1.25;
    color: var(--sv-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.survey-micro-vote {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 5px;
    font: 700 12px/1 "Gotham Book", sans-serif;
    color: var(--sv-accent);
    background: var(--sv-surf);
    border: 1px solid var(--sv-line);
    border-radius: 20px;
    padding: 4px 10px;
    cursor: pointer;
}
.survey-micro-vote[aria-pressed="true"] {
    opacity: 0.55;
    cursor: default;
}
.survey-micro-foot {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--sv-dim);
    padding-top: 7px;
    border-top: 1px solid var(--sv-line);
    margin: 4px 0 0;
}

/* Zero state. No count, no See-all, no drawer affordance anywhere on the
 * slide — nothing promises content that doesn't exist. Most of these
 * campaigns launch empty, so this is the state that ships first. */
.survey-micro-zero {
    flex: 0 0 auto;
    margin-top: clamp(12px, 1.6vw, 22px);
    border: 1px dashed var(--sv-line);
    border-radius: 10px;
    background: var(--sv-surf);
    padding: 16px 14px;
    text-align: center;
    font-family: "Gotham Book", sans-serif;
}
.survey-micro-zero b {
    display: block;
    font-size: 13px;
    color: var(--sv-fg);
    margin-bottom: 3px;
}
.survey-micro-zero span {
    display: block;
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--sv-dim);
}

/* ---- the drawer ---------------------------------------------------- */
.survey-drawer {
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: #faf9f7;
    color: #1a1a1a;
    border-left: 1px solid #e6e4df;
    font-family: "Gotham Book", sans-serif;
}
.hys-section--dark .survey-drawer {
    background: #141414;
    color: #fff;
    border-left-color: #2a2a2a;
}
.survey-drawer-head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 18px 22px 10px;
}
.survey-drawer-head h3 {
    margin: 0;
    font: 800 17px/1.1 inherit;
    white-space: nowrap;
}
.survey-drawer-count {
    font-size: 12px;
    color: #8a857d;
    font-weight: 600;
}
.survey-drawer-x {
    margin-left: auto;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1px solid #e6e4df;
    background: #fff;
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    color: #5c5750;
    flex: 0 0 auto;
}
.hys-section--dark .survey-drawer-x {
    background: #1f1f1f;
    border-color: #333;
    color: #ddd;
}
.survey-drawer-x:hover {
    background: #1a1a1a;
    color: #fff;
    border-color: #1a1a1a;
}
.survey-drawer-tools {
    flex: 0 0 auto;
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 0 22px 12px;
}
.survey-chip {
    font: 700 11px/1 inherit;
    padding: 7px 12px;
    border-radius: 20px;
    border: 1px solid #e0ddd6;
    background: #fff;
    color: #5c5750;
    cursor: pointer;
}
.hys-section--dark .survey-chip {
    background: #1f1f1f;
    border-color: #333;
    color: #bbb;
}
.survey-chip.is-on {
    background: #1a1a1a;
    color: #fff;
    border-color: #1a1a1a;
}
.hys-section--dark .survey-chip.is-on {
    background: #fff;
    color: #111;
    border-color: #fff;
}
.survey-drawer-search {
    flex: 1 1 auto;
    min-width: 0;
    border: 1px solid #e0ddd6;
    border-radius: 20px;
    padding: 7px 12px;
    font-size: 12px;
    background: #fff;
    color: #5c5750;
}
.hys-section--dark .survey-drawer-search {
    background: #1f1f1f;
    border-color: #333;
    color: #ccc;
}
.survey-drawer-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 22px 14px;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 9px;
    align-content: start;
}
.survey-card {
    border: 1px solid #e6e4df;
    border-radius: 10px;
    background: #fff;
    padding: 9px 11px;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.hys-section--dark .survey-card {
    background: #1c1c1c;
    border-color: #2e2e2e;
}
.survey-card-top {
    display: flex;
    align-items: flex-start;
    gap: 9px;
}
.survey-card-rank {
    flex: 0 0 auto;
    font: 800 11px/1 inherit;
    color: #a9a49b;
    padding-top: 3px;
    min-width: 16px;
}
.survey-card-name {
    font: 700 14px/1.2 inherit;
    margin: 0 0 1px;
    overflow-wrap: anywhere;
}
.survey-card-place {
    font-size: 11.5px;
    color: #8a857d;
    margin: 0;
}
.survey-card-bar {
    height: 4px;
    border-radius: 3px;
    background: #ebe8e2;
    margin-top: auto;
    overflow: hidden;
}
.hys-section--dark .survey-card-bar {
    background: #2a2a2a;
}
.survey-card-bar i {
    display: block;
    height: 100%;
    background: var(--color-rov-green);
    border-radius: 3px;
}
.survey-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 10.5px;
    color: #a9a49b;
    margin-top: 6px;
}
.survey-card-vote {
    flex: 0 0 auto;
    border: 2px solid var(--color-rov-green);
    background: #fff;
    color: var(--color-rov-green);
    border-radius: 8px;
    padding: 5px 10px;
    font: 700 11.5px/1 inherit;
    cursor: pointer;
    white-space: nowrap;
}
.hys-section--dark .survey-card-vote {
    background: transparent;
}
.survey-card-vote:hover:not([aria-pressed="true"]) {
    background: var(--color-rov-green);
    color: #fff;
}
.survey-card-vote[aria-pressed="true"] {
    background: #e9ecef;
    border-color: #adb5bd;
    color: #6c757d;
    cursor: default;
}
.hys-section--dark .survey-card-vote[aria-pressed="true"] {
    background: #242424;
    border-color: #3a3a3a;
    color: #777;
}
.survey-drawer-empty {
    grid-column: 1 / -1;
    text-align: center;
    color: #8a857d;
    background: #f1f0ec;
    border-radius: 12px;
    padding: 2.4rem 1rem;
    font-size: 13px;
}
.hys-section--dark .survey-drawer-empty {
    background: #1c1c1c;
}
.survey-drawer-foot {
    flex: 0 0 auto;
    /* Opaque: the grid scrolls right up to it, and a transparent footer let
     * the last card's white box read through its own text. */
    background: inherit;
    padding: 10px 22px 16px;
    font-size: 11.5px;
    color: #8a857d;
    border-top: 1px solid #eeece7;
    margin: 0;
}
.hys-section--dark .survey-drawer-foot {
    border-top-color: #2a2a2a;
}

/* ---- below 1000px: the drawer stops being a column ------------------ *
 * A third column can't be paid for out of a 900px-wide slide — opening it
 * would leave the photo a 90px strip. It becomes an overlay instead, which
 * also means the shell keeps its honest 100% width and only the drawer
 * transforms. Two mechanics for one component is a real cost, but the
 * alternative is a layout that shrinks to nonsense. */
@media (max-width: 999px) {
    .hys-section .survey-shell {
        width: 100% !important;
    }
    /* Fixed, not absolute. On a phone the slide is a metre tall and the
     * reader is somewhere in the middle of it; an overlay pinned to the
     * SECTION would open above or below the fold. Fixed pins it to the
     * viewport, which is what "drawer" means on a phone anyway. */
    .survey-drawer {
        position: fixed;
        /* Below the two sticky bars, not under them: at top:0 the site header
         * and the jump nav painted straight over the drawer's own header —
         * which is where its only close button lives. */
        top: calc(var(--hys-header-h) + var(--hys-nav-h));
        right: 0;
        /* Height, not `bottom: 0`. On iOS a fixed element's bottom edge is the
         * LAYOUT viewport, which sits above Safari's floating toolbar — the
         * drawer stopped ~90px short and the slide showed through underneath.
         * 100dvh is the visible height, toolbar included. */
        bottom: auto;
        height: calc(100dvh - var(--hys-header-h) - var(--hys-nav-h));
        width: min(92%, 460px);
        z-index: 120;
        /* Parked a shadow's width clear of the edge, not the bare 101% it used
         * to be. 101% of a 345pt drawer is 3pt of clearance, and the box-shadow
         * below reaches 36pt further left than the panel does (16pt offset plus
         * half of a 40pt blur) — so the closed drawer painted a permanent dark
         * band down the right-hand third of every survey slide on a phone. It
         * read as a rendering fault on the photo, which is where it was found.
         * The extra 48px costs nothing: the panel is off-screen either way and
         * the transition is on transform. */
        transform: translateX(calc(100% + 48px));
        transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: -16px 0 40px rgb(0 0 0 / 0.35);
        border-left: 0;
    }
    .survey-shell.is-subs-open .survey-drawer {
        transform: none;
    }
    .survey-drawer-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Tablet: still two real columns, photo beside the rail. */
@media (min-width: 768px) and (max-width: 999px) {
    .hys-section .survey-shell {
        grid-template-columns: minmax(0, 1fr) clamp(320px, 42vw, 400px) !important;
        grid-template-rows: minmax(0, 1fr) !important;
        max-width: none !important;
    }
    .hys-section .survey-shell .homepage-survey-photo {
        grid-area: 1 / 1 / 2 / 2 !important;
        height: auto;
    }
    /* Here the rail IS the right edge of the slide, so the share chip lands
     * on the headline's last word. (At 1000px+ the chip sits over the parked
     * drawer's column instead and this isn't needed.) */
    .hys-section .survey-rail .homepage-survey-title {
        padding-right: 42px !important;
    }
}

/* ---- phones -------------------------------------------------------- *
 * A survey slide with a list on it can't be a fixed-height slide any more:
 * headline + form + even five answers is taller than 100svh on a 667px
 * phone, and .hys-section clips overflow, so the honest fix is to let these
 * sections grow and the page scroll — exactly what the Caption Challenge
 * and the State Challenge already do at this width. */
@media (max-width: 767px) {
    .hys-section--survey {
        height: auto;
        min-height: 0;
        overflow: visible;
    }
    .hys-section--survey .homepage-survey-container,
    .hys-section--survey .survey-shell {
        height: auto;
    }
    .hys-section .survey-rail {
        box-shadow: none;
        padding: 18px 18px 26px;
    }
    /* The photo stops being half a slide and becomes a banner. Contained on
     * the slide's own colour, so a portrait shot letterboxes rather than
     * being centre-cropped to a strip.
     *
     * The banner is sized by RATIO, not by a viewport height, and that is the
     * whole point — an earlier `aspect-ratio:auto; height:34svh` shrank the
     * picture to a stamp on a real phone. Two things did it, and the second
     * one hid the first in devtools:
     *
     *   1. `background-size:contain` fits the picture inside the box on BOTH
     *      axes, so the painted width can never exceed the box HEIGHT for a
     *      square source. Two of the six survey photos are exactly 1:1 (bridge
     *      700x700, diner 768x768) and the beach is 1.04:1, so a 375-wide box
     *      only ever painted `height` px of picture and filled the rest with
     *      tan. A height-driven box CANNOT produce a full-width banner here.
     *   2. `svh` is the SMALL viewport — the one with Safari's toolbars shown.
     *      Device-emulating desktop Chrome has no toolbars, so 100svh there is
     *      the whole 667px window and 34svh measured a forgiving 227px. On an
     *      iPhone SE running iOS 26, 100svh is 549pt, so 34svh is 187pt and the
     *      picture collapsed to a 187pt square adrift in the slide. Same bug in
     *      both engines; only iOS made it obvious.
     *
     * So the box gets a 1:1 ratio instead, which is what custom.css already
     * declares at this width — this rule no longer fights it, it just stops
     * the height from overriding it. Every landscape source (bar 1.47:1,
     * beach 1.04:1) now runs edge to edge and letterboxes onto the slide's own
     * colour, which is the intended look; the square ones fill it exactly. The
     * two portrait sources (museum 3:4, concert 6:7) still pillarbox, because
     * a tall picture cannot fill a square box without the crop we refuse to do.
     *
     * No !important, and no floor. Nothing in survey.php's class list touches
     * width/height/aspect-ratio at this width, and this selector already
     * out-ranks custom.css's own unscoped copy inside `app`. The old
     * `min-height:200px` is gone rather than re-flagged: the markup carries
     * the `min-h-0` utility, utilities sit in a layer above `app`, so that
     * floor computed to 0px on every engine from the day it was written — it
     * was never what was holding the banner up. A ratio needs no floor. */
    .hys-section--survey .homepage-survey-photo {
        height: auto;
        aspect-ratio: 1 / 1;
    }
    .hys-section .survey-rail .homepage-survey-title {
        text-align: center !important;
        font-size: clamp(1.75rem, 8.5vw, 2.4rem) !important;
    }
    .hys-section .survey-rail .homepage-survey-subtitle {
        text-align: center !important;
    }
    .hys-section .survey-rail .homepage-survey-label {
        font-size: 0.9rem !important;
        width: 6.2em !important;
    }
    .hys-section .survey-rail .homepage-survey-input {
        padding: 0.5rem 0.7rem !important;
        font-size: 1rem !important; /* 16px — anything less and iOS zooms the page on focus */
    }
    /* The micro list is capped rather than clipped-to-fit: with the page
     * scrolling there is no height to fill, and an uncapped list would push
     * the next slide a screen and a half down. Six rows is the tease; the
     * drawer is the rest. */
    .survey-micro {
        flex: 0 0 auto;
        margin-top: 20px;
        padding-top: 14px;
        border-top: 1px solid var(--sv-line);
    }
    .survey-micro-list {
        max-height: 244px;
    }
    .survey-micro-list li {
        padding: 9px 2px; /* 40px rows — a real tap target for the vote pill */
    }
    .survey-micro-vote {
        padding: 8px 12px;
    }
    .survey-drawer-head,
    .survey-drawer-tools,
    .survey-drawer-grid,
    .survey-drawer-foot {
        padding-left: 16px;
        padding-right: 16px;
    }
    /* Two chips and a search field in ~310px leaves the field about eight
     * characters wide, which reads as broken. It gets its own line. */
    .survey-drawer-tools {
        flex-wrap: wrap;
    }
    .survey-drawer-search {
        flex: 1 0 100%;
        padding: 9px 14px;
        font-size: 16px; /* iOS zooms the page on focus below 16px */
    }
    .survey-chip {
        padding: 9px 14px;
    }
    /* The header, the chips and the search field already cost ~120pt of a
     * 667pt phone. Trimming the cards' own chrome (not their tap targets) is
     * what buys the fourth card back into view. */
    .survey-drawer-head {
        padding: 12px 16px 6px;
    }
    .survey-card {
        padding: 7px 10px;
    }
    .survey-card-name {
        font-size: 13.5px;
    }
    .survey-card-meta {
        margin-top: 4px;
    }
    .survey-drawer-foot {
        padding-top: 7px;
        padding-bottom: 9px;
        font-size: 10.5px;
        line-height: 1.35;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hys-section .survey-shell,
    .survey-drawer {
        transition: none;
    }
}

/* ------------------------------------------------------------------ *
 * 02 · Caption Challenge
 *
 * Photograph left, panel right, winners archive as a drawer.
 *
 * THE DRAWER never re-lays out. It is in the DOM at its final width from the
 * start, parked just off the right edge because the component is wider than
 * its container by exactly that amount. Opening shrinks the component to 100%,
 * so the photo yields and the drawer travels in already-formed. Animating the
 * drawer's own width instead would reflow every card inside it mid-transition,
 * which is what made an earlier version look like it was being built on click.
 * ------------------------------------------------------------------ */
#hys-caption{ background:#000; }

.cc{
    --cc-panel: clamp(340px, 28vw, 440px);
    --cc-drawer: min(46vw, 620px);
    height:100%;
    width:calc(100% + var(--cc-drawer));
    display:grid;
    grid-template-columns: minmax(0,1fr) var(--cc-panel) var(--cc-drawer);
    grid-template-rows: minmax(0,1fr);
    grid-template-areas: "shot panel drawer";
    transition: width .45s cubic-bezier(.4,0,.2,1);
}
.cc.cc-showAll{ width:100%; }

.cc-shot{grid-area:shot;}
.cc-panel{grid-area:panel;}
.cc-drawer{grid-area:drawer;}

/* --- the photograph: its own aspect ratio, on black, never cropped --- */
.cc-shot{
    background:#000;display:flex;align-items:center;justify-content:center;
    padding:clamp(12px,1.6vw,22px);min-height:0;overflow:hidden;position:relative;
}
.cc-shot img{max-height:100%;width:auto;object-fit:contain;
    box-shadow:0 10px 34px rgb(0 0 0 / 0.5);}
.cc.cc-showAll .cc-shot{cursor:zoom-out;}
.cc.cc-showAll .cc-shot::after{
    content:"Click to close";position:absolute;left:50%;bottom:14px;transform:translateX(-50%);
    font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
    color:#fff;background:rgb(255 255 255 / 0.18);padding:5px 10px;border-radius:20px;white-space:nowrap;
}

/* --- the panel --- */
.cc-panel{display:flex;flex-direction:column;min-height:0;background:#fff;z-index:3;
    box-shadow:-10px 0 26px rgb(0 0 0 / 0.18);}
.cc-head{padding:clamp(14px,1.8vw,22px) clamp(14px,1.8vw,24px) 0;}
#hys-caption .cc-head h2{font-size:clamp(1.05rem,1.4vw,1.3rem);font-weight:800;margin:0 0 2px;}
.cc-sub{font-size:12.5px;color:#6c757d;margin:0 0 14px !important;}
.cc-admin{padding:.5rem 1rem !important;margin-bottom:.6rem !important;font-size:.82rem;}
.cc-submitRow{display:flex;gap:8px;margin-bottom:.4rem;}
#hys-caption .cc-submitRow .r1v-input{height:38px;}
.cc-capsHead{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px;
    margin:14px 0 7px;font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
    color:#8a857d;}
.cc-capsHead b{color:#1a1a1a;}

/* Community captions scroll; the fade is the "more below" cue. */
.cc-caps{flex:1;min-height:0;overflow-y:auto;padding:0 clamp(14px,1.8vw,24px) 4px;
    display:flex;flex-direction:column;gap:6px;
    mask-image:linear-gradient(to bottom,#000 calc(100% - 22px),transparent 100%);
    -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 22px),transparent 100%);}
.cc-empty{text-align:center;color:#6c757d;font-style:italic;padding:1.5rem 0;}
#hys-caption .caption-card{display:flex;align-items:center;gap:10px;background:#f1f3f5;
    border-radius:8px;padding:7px 10px;flex:0 0 auto;margin:0;}
.cc-capText{flex:1;min-width:0;font-size:13.5px;line-height:1.3;}
.cc-capText small{display:block;color:#6c757d;font-size:11.5px;margin-top:2px;}
.cc-capVote{display:flex;align-items:center;gap:8px;flex-shrink:0;}
#hys-caption .caption-vote-btn{border:2px solid var(--color-rov-green);background:#fff;
    color:var(--color-rov-green);border-radius:8px;padding:5px 11px;font-size:12px;font-weight:700;
    cursor:pointer;white-space:nowrap;transition:all .2s;}
#hys-caption .caption-vote-btn:hover:not(:disabled){background:var(--color-rov-green);color:#fff;}
#hys-caption .caption-vote-btn:disabled,
#hys-caption .caption-vote-btn.voted{background:#e9ecef;border-color:#adb5bd;color:#6c757d;
    cursor:not-allowed;}
#hys-caption .caption-vote-count{font-weight:800;color:var(--color-rov-green);min-width:20px;
    text-align:center;font-size:14px;}

/* --- winners teaser, pinned to the foot of the panel --- */
.cc-winTeaser{flex:0 0 auto;border-top:1px solid #e6e4df;
    padding:10px clamp(14px,1.8vw,24px) clamp(12px,1.6vw,18px);}
#hys-caption .cc-winTeaser h3{display:flex;align-items:center;justify-content:space-between;
    font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#8a857d;
    margin:0 0 8px;}
.cc-viewAll{font-size:11px;font-weight:700;color:var(--color-rov-green);text-transform:none;
    letter-spacing:0;cursor:pointer;background:none;border:0;font-family:inherit;}
.cc-viewAll:hover{text-decoration:underline;}
.cc-winRow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;}

/* Winner thumbnails: the TILE holds one fixed shape so the grid stays aligned,
 * the PHOTO keeps its own aspect ratio inside it on black. Never cropped, and
 * never re-proportioned by whatever space the drawer happens to have. */
#hys-caption .caption-winner-card{border:1px solid #e6e4df;border-radius:8px;overflow:hidden;
    background:#fff;display:flex;flex-direction:column;min-width:0;}
#hys-caption .caption-winner-card img{aspect-ratio:3/2;width:100%;height:auto;
    object-fit:contain;background:#000;color:transparent;font-size:0;}
#hys-caption .caption-winner-card p{font-size:10.5px;line-height:1.2;padding:5px 6px;margin:0;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}

/* --- the drawer --- */
.cc-drawer{min-height:0;background:#faf9f7;border-left:1px solid #e6e4df;
    display:flex;flex-direction:column;}
.cc-drawerHead{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;
    padding:clamp(14px,1.8vw,20px) clamp(14px,1.8vw,22px) 10px;}
#hys-caption .cc-drawerHead h3{font-size:1.05rem;font-weight:800;white-space:nowrap;margin:0;}
.cc-cnt{font-size:12px;color:#8a857d;margin-left:8px;font-weight:600;}
.cc-closeX{width:32px;height:32px;border-radius:50%;border:1px solid #e6e4df;background:#fff;
    cursor:pointer;font-size:13px;color:#5c5750;flex:0 0 auto;}
.cc-closeX:hover{background:#1a1a1a;color:#fff;border-color:#1a1a1a;}
.cc-winGrid{flex:1;min-height:0;padding:0 clamp(14px,1.8vw,22px) 12px;
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;
    align-content:start;overflow:hidden;}
#hys-caption .cc-winGrid .caption-winner-card p{font-size:12.5px;line-height:1.3;
    padding:2px 9px 9px;-webkit-line-clamp:3;}
.cc-mo{font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
    color:var(--color-rov-green);padding:7px 9px 0;}
.cc-drawerFoot{flex:0 0 auto;padding:0 clamp(14px,1.8vw,22px) 14px;font-size:12px;color:#8a857d;margin:0;}

.cc-none{grid-column:1/-1;align-self:center;justify-self:center;text-align:center;
    background:#f1f3f5;border-radius:12px;padding:3rem;color:#6c757d;}

/* --- intermediate: photo left, quiz beside it, contenders full width below --- */
@media (max-width:1199px) and (min-width:900px){
    #hys-caption{height:auto;min-height:var(--hys-slide-h);overflow:visible;}
    .cc{height:auto;
        grid-template-rows: minmax(0,52svh) auto auto;
        grid-template-areas:
            "shot  quiz  drawer"
            "caps  caps  drawer"
            "wins  wins  drawer";}
    .cc-panel{display:contents;}
    .cc-head{grid-area:quiz;display:flex;flex-direction:column;justify-content:center;
        background:#fff;padding:clamp(14px,1.8vw,22px) clamp(14px,1.8vw,24px);}
    /* Too narrow to sit a button beside the field without truncating it. */
    .cc-submitRow{flex-direction:column;}
    .cc-submitRow .r1v-btn{width:100%;justify-content:center;}
    .cc-caps{grid-area:caps;overflow:visible;max-height:none;background:#fff;
        mask-image:none;-webkit-mask-image:none;
        padding:14px clamp(14px,2vw,26px);border-top:1px solid #e6e4df;}
    .cc-winTeaser{grid-area:wins;background:#fff;}
    .cc-shot{max-height:52svh;}
    .cc-drawer{position:sticky;top:0;height:var(--hys-slide-h);}
    /* Fewer columns rather than smaller thumbnails. */
    .cc-winGrid{grid-template-columns:repeat(2,minmax(0,1fr));}
    #hys-caption .caption-winner-card p{font-size:12px;}
}

/* The quiz stops being a fixed-height slide on a phone too: the bank and the
 * drop zones stack, and any leftover slide height was being distributed as a
 * gap between them rather than tightening up. */
@media (max-width:899px){
    #hys-states{height:auto;min-height:0;overflow:visible;}
    #hys-states > .container,
    #hys-states #stateDragDropQuiz > div,
    #hys-states #quizGame,
    #hys-states .game-layout{flex:0 0 auto;}
    #hys-states .game-layout{display:flex;flex-direction:column;gap:0.75rem;}
    #hys-states .state-grid{grid-auto-rows:auto;}
    #hys-states .state-box{aspect-ratio:1/1 !important;}
}

/* --- mobile: one honest column, page scrolls --- */
@media (max-width:899px){
    #hys-caption{height:auto;min-height:0;overflow:visible;}
    .cc, .cc.cc-showAll{width:100%;display:flex;flex-direction:column;height:auto;}
    .cc-shot{flex:0 0 auto;max-height:46svh;padding:14px;}
    .cc-shot img{max-height:44svh;}
    .cc.cc-showAll .cc-shot::after{display:none;}
    .cc-panel{box-shadow:none;}
    .cc-caps{max-height:none;overflow:visible;mask-image:none;-webkit-mask-image:none;
        padding-bottom:14px;}
    /* Same reason as the tablet regime: a field and a button side by side at
       this width truncates the placeholder to "Enter your witty caption". */
    .cc-submitRow{flex-direction:column;}
    .cc-submitRow .r1v-btn{width:100%;justify-content:center;}
    .cc-drawer{border-left:0;border-top:1px solid #e6e4df;}
    .cc:not(.cc-showAll) .cc-drawer{display:none;}
    .cc-winGrid{grid-template-columns:repeat(2,minmax(0,1fr));overflow:visible;}
}

/* ------------------------------------------------------------------ *
 * PREVIEW MODE notice — paired with $hysPreviewMode in the page template.
 * Delete this block when the flag goes.
 * ------------------------------------------------------------------ */
.hys-preview-notice {
    position: fixed;
    left: 50%;
    bottom: 26px;
    transform: translate(-50%, 14px);
    z-index: 200;
    max-width: min(92vw, 460px);
    background: #1a1a1a;
    color: #fff;
    padding: 13px 20px;
    border-radius: 26px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    text-align: center;
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease;
}
.hys-preview-notice.is-on {
    opacity: 1;
    transform: translate(-50%, 0);
}

@media (prefers-reduced-motion:reduce){ .cc{transition:none;} }

/* ------------------------------------------------------------------ *
 * 03 · State Challenge
 *
 * The hardest slide to fit: 15 name chips beside 15 drop zones. It gets the
 * whole slide — the dark header strip is trimmed to a band and the card
 * below it takes every remaining pixel, so the tiles are as large as they
 * can be rather than squashed with a gap underneath.
 * ------------------------------------------------------------------ */
#hys-states {
    background-color: #fff;
}
/* No dark title band here. It exists so the quiz can introduce itself when
 * it's dropped into a page of other content; on this page the jump nav above
 * already names the slide, so the band is a redundant ~90px. The container is
 * kept (it carries the #state-quiz anchor and the share button) but reduced to
 * the one line that still earns its place: the instruction. */
#hys-states .quiz-hero {
    flex: 0 0 auto;
    background: transparent !important;
    padding: 0.5rem 1rem 0.35rem !important;
}
#hys-states .quiz-hero-title {
    display: none;
}
#hys-states .quiz-hero p {
    color: #6b6b6b !important;
    font-size: 0.85rem !important;
    margin: 0 !important;
}
#hys-states > .container {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    margin-top: 0 !important;
    padding-bottom: 0.5rem;
}
#hys-states #stateDragDropQuiz > div,
#hys-states #quizGame {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    margin-bottom: 0 !important;
    padding: 0.6rem !important;
}
#hys-states .quiz-stats,
#hys-states #quizGame > .flex.justify-between {
    flex: 0 0 auto;
    padding: 0.4rem 0.75rem !important;
    margin-bottom: 0.5rem !important;
}
#hys-states #quizGame > .flex.justify-between .small,
#hys-states #quizGame > .flex.justify-between .text-gray-600 {
    font-size: 0.7rem !important;
    margin-bottom: 0 !important;
}
#hys-states .game-layout {
    flex: 1 1 auto;
    min-height: 0;
    align-items: stretch;
}
/* Stretch, not h-fit: a name panel that stops short of the drop-zone grid
 * leaves a stray notch of white down the left of the slide. */
/* Full height, not h-fit: a name panel that stops short of the drop-zone grid
 * leaves a stray notch of white down the left of the slide. !important beats
 * the template's own `h-fit`. Only where the two sit side by side — stacked,
 * a full-height panel is just a box of dead space above the tiles. */
#hys-states .quiz-bank-sticky {
    padding: 0.5rem !important;
    overflow-y: auto;
}
@media (min-width: 992px) {
    #hys-states .quiz-bank-sticky {
        height: 100% !important;
        align-self: stretch;
        /* Column so #stateNamesBank below the h3 can be told to fill
         * whatever height is left, rather than sizing to its own content
         * and leaving the rest of the sticky panel empty. */
        display: flex;
        flex-direction: column;
    }
    #hys-states #stateNamesBank {
        flex: 1 1 auto;
        min-height: 0;
        height: auto;
    }
    /* Chips grow to share out the bank's full height instead of bunching at
     * the top at a fixed small size. Bounded by max-height so that as chips
     * are removed on match (state-drag-drop.js) the last few remaining
     * don't balloon into oversized blocks. */
    #hys-states .state-name-chip {
        flex: 1 1 0;
        min-height: 2rem;
        max-height: 3.75rem;
        display: flex;
        align-items: center;
    }
}
#hys-states .quiz-bank-sticky h3 {
    font-size: 0.85rem !important;
    margin-bottom: 0.3rem !important;
}
#hys-states #stateNamesBank {
    gap: 0.25rem !important;
}
#hys-states .state-name-chip {
    padding: 0.35rem 0.6rem !important;
    font-size: 0.85rem !important;
    line-height: 1.2 !important;
}
/* Drop zones share out whatever height is left, rather than being pinned to
 * a square that may not fit. */
#hys-states .state-grid {
    min-height: 0;
    grid-auto-rows: 1fr;
    gap: 0.4rem !important;
}
#hys-states .state-box {
    aspect-ratio: auto !important;
    max-width: none !important;
    min-height: 0;
    padding: 0.25rem !important;
}
#hys-states .state-box svg {
    max-width: 100%;
    max-height: 100%;
    height: 100%;
}

}
