:root {
    --cream: #f4efe6;
    --orange: #e8501a;
    --amber: #f6b21b;
    --brown: #2a2018;
    --font-heading: Georgia, "Times New Roman", serif;
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--cream);
    color: var(--brown);
    font-family: var(--font-body);
    line-height: 1.5;
}

/* Ticket 36: a defence, not a fix. The owner saw a very slight sideways
   scroll on a real phone that emulation at 375px never reproduced
   (scrollWidth == clientWidth on every public page, mid-play included), so
   the public pages clip rather than scroll whatever pokes past the edge.
   clip, not hidden: hidden would make the body a scroll container.
   The admin shares this stylesheet and is left out on purpose — there a wide
   page should stay reachable, not be cut off. Two rules, not one list: a
   browser without :has() then drops only the html half. */
body:not(.admin) {
    overflow-x: clip;
}

html:has(> body:not(.admin)) {
    overflow-x: clip;
}

h1,
h2,
h3 {
    font-family: var(--font-heading);
    font-weight: 700;
}

.site-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    border-bottom: 4px solid var(--orange);
}

.site-header .roundel {
    width: 48px;
    height: 48px;
}

.site-header .wordmark {
    height: 40px;
    width: auto;
}

.brand-text {
    font-family: var(--font-heading);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--orange);
    white-space: nowrap;
}

.hero {
    flex: 1;
    /* Fixed column: without width, a flex item with auto margins shrink-wraps
       its content, so the quiz buttons would resize as answers reveal text. */
    width: 100%;
    max-width: 34rem;
    margin: 0 auto;
    padding: 3rem 1.25rem;
    text-align: center;
}

.hero h1 {
    font-size: 2.5rem;
    margin: 0 0 1rem;
    color: var(--orange);
}

.strapline {
    font-size: 1.125rem;
}

.coming-soon {
    display: inline-block;
    margin-top: 1.5rem;
    padding: 0.75rem 1.5rem;
    background: var(--amber);
    border-radius: 999px;
    font-weight: 600;
}

/* Quiz page */

[x-cloak] {
    display: none !important;
}

.quiz-photo {
    max-width: 100%;
    border-radius: 12px;
    border: 4px solid var(--brown);
}

.image-credit {
    margin: 0.25rem 0 0;
    font-size: 0.75rem;
    opacity: 0.7;
}

.subject-title {
    font-family: var(--font-heading);
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0 0 1rem;
}


/* What the player's script scrolls to comes to rest a little clear of the
   screen edge rather than flush against it. */
.quiz-app section,
.quiz-app .feedback,
.quiz-app .score-line {
    scroll-margin: 1rem;
}

.btn-primary,
.btn-secondary {
    display: inline-block;
    padding: 0.875rem 2rem;
    border: none;
    border-radius: 999px;
    font-size: 1.125rem;
    font-weight: 700;
    cursor: pointer;
}

.btn-primary {
    background: var(--orange);
    color: var(--cream);
}

.btn-secondary {
    background: var(--amber);
    color: var(--brown);
}

.progress {
    font-size: 0.875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    opacity: 0.7;
}

.question-text {
    font-size: 1.5rem;
    margin: 0.5rem 0 1.25rem;
}

.options {
    display: grid;
    gap: 0.75rem;
}

.option {
    padding: 1rem 1.25rem;
    background: #fff;
    border: 2px solid var(--brown);
    border-radius: 12px;
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--brown);
    text-align: left;
    cursor: pointer;
    /* The option's text, with its share of the players pushed to the end once
       the answer is in. One row, always: the wording wraps inside its own span,
       so a two-line option keeps its percentage at the end rather than dropping
       it onto a second flex line, bottom-left. */
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

.option-text {
    /* Takes the room left over and wraps within it; min-width lets a long
       word break instead of stretching the row. */
    flex: 1 1 auto;
    min-width: 0;
}

.option-share {
    flex: 0 0 auto;
    font-size: 0.875rem;
    font-weight: 700;
    opacity: 0.7;
    white-space: nowrap;
}

.option:not(:disabled):hover {
    border-color: var(--orange);
}

.option.correct {
    background: var(--amber);
    border-color: var(--brown);
}

.option.wrong {
    background: var(--orange);
    border-color: var(--brown);
    color: var(--cream);
}

.option.dimmed {
    opacity: 0.5;
}

.feedback {
    margin-top: 1.25rem;
}

.verdict {
    font-family: var(--font-heading);
    font-size: 1.25rem;
    font-weight: 700;
    margin: 0 0 0.25rem;
}

.answer-stat {
    font-size: 0.9375rem;
    font-weight: 600;
    opacity: 0.8;
    margin: 0 0 0.5rem;
}

.explanation {
    margin: 0 0 1rem;
}

.score-line {
    font-size: 1.5rem;
    margin: 0.5rem 0;
}

.persona {
    font-family: var(--font-heading);
    font-size: 2rem;
    font-weight: 700;
    color: var(--orange);
    margin: 0 0 1.5rem;
}

.story {
    text-align: left;
    background: #fff;
    border: 2px solid var(--brown);
    border-radius: 12px;
    padding: 1rem 1.25rem;
}

.come-back {
    display: inline-block;
    margin-top: 0.75rem;
    padding: 0.75rem 1.5rem;
    background: var(--amber);
    border-radius: 999px;
    font-weight: 600;
}

.sample-note {
    margin-top: 1.5rem;
    font-size: 0.875rem;
    opacity: 0.7;
}

.site-footer {
    padding: 1rem 1.25rem;
    text-align: center;
    font-size: 0.8125rem;
    background: var(--brown);
    color: var(--cream);
}

.site-footer p {
    margin: 0 auto;
    max-width: 44rem;
}

/* --- Ticket 03: permalinks, archive, share --- */

.site-brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    text-decoration: none;
}

.site-nav {
    margin-left: auto;
}

.site-nav a,
.archive-link {
    font-weight: 600;
    color: var(--brown);
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}

.beat-line {
    font-family: var(--font-heading);
    font-size: 1.125rem;
    font-weight: 700;
    margin: -0.75rem 0 1rem;
}

.replay-note {
    font-size: 0.9375rem;
    opacity: 0.75;
    margin: 0 0 1rem;
}

.share {
    margin: 0 0 1.5rem;
}

.share-fallback {
    display: block;
    margin-top: 0.75rem;
    font-size: 0.875rem;
    text-align: left;
}

.share-fallback textarea {
    width: 100%;
    margin-top: 0.25rem;
    padding: 0.5rem;
    border: 2px solid var(--brown);
    border-radius: 8px;
    font: inherit;
    font-size: 0.875rem;
}

a.come-back {
    text-decoration: none;
    color: var(--brown);
}

.archive {
    flex: 1;
    max-width: 40rem;
    margin: 0 auto;
    padding: 2.5rem 1.25rem;
    width: 100%;
}

.archive h1 {
    font-size: 2rem;
    margin: 0 0 0.5rem;
}

.archive .strapline {
    margin: 0 0 1.5rem;
}

.archive-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.75rem;
}

.archive-entry a {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.625rem;
    background: #fff;
    border: 2px solid var(--brown);
    border-radius: 12px;
    color: var(--brown);
    text-decoration: none;
}

.archive-thumb {
    width: 72px;
    height: 72px;
    flex: 0 0 72px;
    object-fit: cover;
    border-radius: 8px;
    background: var(--cream);
}

.archive-thumb-empty {
    display: block;
    border: 2px dashed rgba(42, 32, 24, 0.3);
}

.archive-text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.archive-title {
    font-family: var(--font-heading);
    font-size: 1.125rem;
    font-weight: 700;
}

.archive-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
}

.archive-decade {
    padding: 0.125rem 0.5rem;
    background: var(--cream);
    border-radius: 999px;
}

.archive-today {
    padding: 0.125rem 0.5rem;
    background: var(--orange);
    color: var(--cream);
    border-radius: 999px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.archive-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1.5rem;
    font-size: 0.9375rem;
}

.archive-pager a {
    font-weight: 600;
    color: var(--brown);
}

/* --- Ticket 13: basic motion ---
   Only the public player moves, and only enough to stop the flow reading as a
   flowchart. Every rule below is scoped inside .quiz-app, so the reduced-motion
   block at the end switches all of it off in one place. Every entrance is a CSS
   animation on an element Alpine has just revealed or rebuilt, so none of the
   motion costs the page any JavaScript. */

@keyframes rt-fade-up {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
}

@keyframes rt-settle {
    50% {
        transform: scale(0.97);
    }
}

/* Each question is a fresh element (keyed on the index), so moving on plays
   this again. */
.quiz-app .question-card {
    animation: rt-fade-up 200ms ease-out both;
}

/* x-show flips display, which restarts the animation on every reveal. */
.quiz-app .feedback {
    animation: rt-fade-up 200ms ease-out both;
}

/* Verdict colours arrive over a beat instead of snapping. */
.quiz-app .option {
    transition: background-color 200ms ease, border-color 200ms ease,
        color 200ms ease, opacity 200ms ease;
}

/* A brief settle on the button the player actually pressed. */
.quiz-app .option.chosen {
    animation: rt-settle 200ms ease-out;
}

/* The score and its persona arrive one after the other. */
.quiz-app .score-screen .score-line {
    animation: rt-fade-up 200ms ease-out both;
}

.quiz-app .score-screen .persona {
    animation: rt-fade-up 200ms ease-out 70ms both;
}

@media (prefers-reduced-motion: reduce) {
    .quiz-app,
    .quiz-app * {
        animation-duration: 0.01ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0ms !important;
    }
}

/* --- Ticket 31: mobile tap targets, from the 375px audit of 2026-09-16 --- */

/* The Archive link measured 54×21 — thumb-sized only by accident. inline-flex
   grows the hit area while the underline stays around the word itself, and the
   negative inline margin keeps the word where it already sat. */
.site-nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0.5rem;
    margin: 0 -0.5rem;
}

/* Advert slot (ticket 30). Only ever in the page when Ads__Enabled is on and
   Ads__Html carries a snippet — so by default these rules match nothing. On
   brand and honest: a bordered box the width of the content column, its own
   small-caps label, in the flow and never sticky or overlaying anything. */
.advert {
    /* The content column, whichever one it is: the end screen's is 34rem and
       the archive's 40rem, and a slot narrower than the page it interrupts
       would look like a mistake. Filling its container matches both. */
    display: block;
    width: 100%;
    max-width: 100%;
    margin: 2rem auto;
    padding: 0.75rem;
    border: 2px solid var(--brown);
    border-color: color-mix(in srgb, var(--brown) 20%, transparent);
    border-radius: 8px;
    text-align: center;
}

.advert-label {
    margin: 0 0 0.5rem;
    font-size: 0.75rem;
    font-variant: small-caps;
    letter-spacing: 0.08em;
    color: var(--brown);
    opacity: 0.65;
}

/* Whatever the snippet turns out to be, it stays inside the column it was
   given rather than widening the page. */
.advert-body {
    overflow: hidden;
}

.advert-body img,
.advert-body iframe {
    max-width: 100%;
}

/* The archive's slot is a list item: no bullet, no marker. */
.archive-advert {
    list-style: none;
}

/* The Buy link (ticket 32): content that follows the story, so it wears the
   story's voice rather than the advert's chrome. The link itself is a
   full-height tap target; the affiliate label and Amazon's disclosure are
   small print, but readable small print. */
.buy-link {
    margin: 1rem 0 0;
    text-align: left;
}

.buy-link p {
    margin: 0;
}

.buy-link a {
    display: inline-block;
    padding: 0.5rem 0;
    /* Brown text for contrast on cream; the brand orange in the underline. */
    color: var(--brown);
    font-weight: 600;
    text-decoration-color: var(--orange);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}

.affiliate-note,
.affiliate-disclosure {
    font-size: 0.75rem;
    opacity: 0.7;
}

/* Scroll-away hero (owner decision 2026-09-26): the photo stays in the page
   and play pins the question to the top — which only works if there is page
   below to scroll into. The active question section fills the small viewport
   so scrollIntoView can always take the hero off-screen; feedback appearing
   uses the space, and before that it is just quiet background. */
.quiz-app section[x-ref="question"] {
    min-height: calc(100vh - 2rem);
    min-height: calc(100svh - 2rem);
}
