/*
 * Cairn: the game's own styles, on top of the inherited Bootstrap/blog layout.
 *
 * Edited directly rather than compiled from LESS — the LESS build in front_dev
 * belongs to the blog and admin pages it came with, and the game does not need
 * a build step to change a colour.
 */

:root {
    --cairn-ink: #2b2b28;
    --cairn-stone: #7a7266;
    --cairn-parchment: #f6f2e9;
    --cairn-edge: #ded5c4;
    --cairn-warm: #8d6e63;
    --cairn-found: #2e7d32;

    /* The site's own voice, and the fallback for any period that has not been
       given a face. A quest page overrides these two inline with the period's
       typography — see App\Zygote::getPeriodFonts and public/css/fonts.css.
       Custom properties rather than a class per period, because the periods
       themselves are edition data and a clone must not need a stylesheet rule
       for each one it invents. */
    --cairn-font-display: "Playfair Display", Georgia, serif;
    --cairn-font-text: "Playfair Display", Georgia, serif;
}

/* ---- the page itself ----
 *
 * The engraved parchment sits in a fixed layer rather than in
 * `background-attachment: fixed`, which iOS Safari ignores outright, and under
 * a scrim: the artwork has a Big Ben in one corner and body text has to stay
 * readable when it lands on top of it. The colour goes on <html> because a
 * background on <body> would paint over its own z-index:-1 pseudo-layers.
 *
 * The file is a convention — public/images/background.webp — the same way the
 * favicons are. A clone for another country replaces the file and edits
 * nothing.
 */

html {
    background-color: var(--cairn-parchment);
}

/* Bootstrap paints --bs-body-bg here, and a background on <body> covers the
   very layers below. */
body {
    background-color: transparent;
}

body::before,
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

body::before {
    background: url("/images/background.webp") center center / cover no-repeat;
}

body::after {
    background: linear-gradient(180deg, rgba(246, 242, 233, .38), rgba(246, 242, 233, .86));
}

/* A surface that has to hold text over the artwork. */
.cairn-panel {
    background: rgba(246, 242, 233, .94);
    border: 1px solid var(--cairn-edge);
    border-radius: 6px;
    box-shadow: 0 14px 40px rgba(43, 43, 40, .12);
}

.cairn-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- the top bar ----
 *
 * One row at every width. It sticks because the home page gives its first
 * screen to a single large image, and scrolling past that should not mean
 * scrolling back up to reach the quest.
 */

:root {
    --cairn-bar-h: 4.25rem;
}

.cairn-topbar {
    position: sticky;
    top: 0;
    z-index: 900;
    background: rgba(246, 242, 233, .93);
    backdrop-filter: blur(6px);
    border-bottom: 1px solid var(--cairn-edge);
}

/* The blog LESS puts 40px on top of every .container; inside the bar that is
   a 40px hole above the logo. */
.cairn-topbar .container {
    margin-top: 0;
}

/* ---- the editor's strip ----
 * Two sticky bars both pinned to top:0 land on top of each other. The admin
 * strip is a convenience for one person; the site's own bar is not. */
.admin-menu-bar {
    position: static;
}

.admin-bar-inner {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.admin-bar-label {
    font-size: .875rem;
    white-space: nowrap;
}

.admin-bar-menu {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex: 1;
}

.admin-bar-menu nav {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.25rem;
}

.admin-bar-menu a {
    color: #fff;
    text-decoration: none;
    font-size: .875rem;
    white-space: nowrap;
}

.admin-bar-menu a:hover {
    color: #fff;
    text-decoration: underline;
}

.admin-bar-who {
    color: rgba(255, 255, 255, .55);
    font-size: .75rem;
    white-space: nowrap;
}

.admin-bar-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 2.25rem;
    height: 1.9rem;
    margin-left: auto;
    padding: 0 .45rem;
    background: none;
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: 3px;
}

.admin-bar-toggle span {
    display: block;
    height: 2px;
    background: #fff;
}

@media (min-width: 992px) {
    .admin-bar-menu.collapse:not(.show) {
        display: flex;
    }
}

@media (max-width: 991.98px) {
    .admin-bar-inner {
        flex-wrap: wrap;
    }

    .admin-bar-toggle {
        display: flex;
    }

    .admin-bar-menu.collapse.show,
    .admin-bar-menu.collapsing {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: .5rem;
        /* 100% basis, not just width: with the flex-basis of 0 it inherits, it
           fits beside the label and never wraps onto its own line. */
        flex: 1 1 100%;
        padding: .5rem 0 .25rem;
    }

    .admin-bar-menu nav {
        flex-direction: column;
        gap: .5rem;
    }
}

.cairn-topbar-inner {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding-top: .5rem;
    padding-bottom: .5rem;
    min-height: var(--cairn-bar-h);
}

.cairn-brand {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin-right: auto;
    text-decoration: none;
    color: var(--cairn-ink);
}

.cairn-brand-mark {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    flex: none;
}

.cairn-brand-name {
    display: block;
    font-family: var(--cairn-font-display);
    font-size: 1.5rem;
    line-height: 1.05;
}

.cairn-brand-tagline {
    display: block;
    font-size: .7rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-nav {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    margin-left: auto;
}

.cairn-nav-links {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.cairn-nav-links a,
.cairn-account a {
    color: var(--cairn-stone);
    text-decoration: none;
    white-space: nowrap;
}

.cairn-nav-links a {
    border-bottom: 2px solid transparent;
    padding-bottom: 2px;
}

.cairn-nav-links a:hover,
.cairn-account a:hover {
    color: var(--cairn-ink);
}

.cairn-nav-links a:hover {
    border-bottom-color: var(--cairn-edge);
}

.cairn-nav-strong {
    color: var(--cairn-ink);
    font-weight: 600;
}

.cairn-account {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.cairn-account-name {
    color: var(--cairn-ink);
    font-weight: 600;
}

.cairn-nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 2.75rem;
    height: 2.5rem;
    padding: 0 .6rem;
    background: none;
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
}

.cairn-nav-toggle span {
    display: block;
    height: 2px;
    background: var(--cairn-ink);
}

@media (min-width: 992px) {
    /* Bootstrap's collapse hides it; above the fold-out width it is just a row. */
    .cairn-nav.collapse:not(.show) {
        display: flex;
    }
}

@media (max-width: 991.98px) {
    .cairn-topbar-inner {
        flex-wrap: wrap;
    }

    .cairn-nav-toggle {
        display: flex;
    }

    .cairn-nav.collapse.show,
    .cairn-nav.collapsing {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: .75rem;
        width: 100%;
        margin: .5rem 0 .75rem;
    }

    .cairn-nav-links {
        flex-direction: column;
        align-items: flex-start;
        gap: .5rem;
    }
}

/* ---- Bootstrap's blue ----
 *
 * The theme these pages came with is Bootstrap's default: #0d6efd buttons and
 * links, on a site whose entire palette is ink and parchment. Remapped here
 * rather than in app.css because that file is a build artifact of front_dev
 * LESS and `make css` would take the change with it.
 */

.btn-primary,
.btn-primary:disabled {
    background-color: var(--cairn-ink);
    border-color: var(--cairn-ink);
    color: var(--cairn-parchment);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary:not(:disabled):not(.disabled):active {
    background-color: #43423c;
    border-color: #43423c;
    color: #fff;
}

.btn-primary:focus,
.btn-outline-primary:focus,
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    box-shadow: 0 0 0 .2rem rgba(122, 114, 102, .3);
    border-color: var(--cairn-stone);
}

.btn-outline-primary {
    color: var(--cairn-ink);
    border-color: var(--cairn-edge);
}

.btn-outline-primary:hover,
.btn-outline-primary:active {
    background-color: var(--cairn-ink);
    border-color: var(--cairn-ink);
    color: var(--cairn-parchment);
}

.btn-secondary {
    background-color: var(--cairn-stone);
    border-color: var(--cairn-stone);
}

.btn-secondary:hover,
.btn-secondary:focus,
.btn-secondary:active {
    background-color: var(--cairn-ink);
    border-color: var(--cairn-ink);
}

.form-check-input:checked {
    background-color: var(--cairn-ink);
    border-color: var(--cairn-ink);
}

/* Links inside the content, which Bootstrap also paints blue. */
main.container a:not(.btn):not(.cairn-btn):not(.cairn-card):not(.auth-social-btn) {
    color: var(--cairn-warm);
}

main.container a:not(.btn):not(.cairn-btn):not(.cairn-card):not(.auth-social-btn):hover {
    color: var(--cairn-ink);
}

/* ---- the auth pages ----
 *
 * The card came from another project with its own identity: a navy-to-indigo
 * gradient header and a blue button, neither of which has been anywhere near
 * this site. Sign-in is often the second page somebody sees, so it cannot be
 * the one page that looks like somewhere else.
 */

.auth-card .card {
    background: var(--cairn-parchment);
    border: 1px solid var(--cairn-edge) !important;
    border-radius: 6px;
}

.auth-hero {
    background: var(--cairn-ink);
    color: var(--cairn-parchment);
    border-bottom: 3px solid var(--cairn-warm);
}

.auth-hero h1 {
    font-family: var(--cairn-font-display);
    font-weight: 400;
    font-size: 1.7rem;
}

.auth-hero p {
    color: rgba(246, 242, 233, .72);
}

.auth-body {
    background: var(--cairn-parchment);
}

.auth-body .form-control {
    background: #fff;
    border-color: var(--cairn-edge);
}

.auth-divider {
    color: var(--cairn-stone);
}

.auth-social-btn {
    border-color: var(--cairn-edge) !important;
    color: var(--cairn-ink) !important;
}

.auth-foot {
    color: var(--cairn-stone);
}

/* ---- buttons ----
 * Bootstrap's primary blue has no place on parchment. */

.cairn-btn {
    display: inline-block;
    font-family: var(--cairn-font-display);
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: 4px;
    padding: .55rem 1.4rem;
    cursor: pointer;
}

.cairn-btn-play {
    background: var(--cairn-ink);
    color: var(--cairn-parchment);
    font-size: 1.15rem;
    padding: .85rem 2.2rem;
    box-shadow: 0 6px 18px rgba(43, 43, 40, .22);
}

.cairn-btn-play:hover {
    background: #43423c;
    color: #fff;
}

.cairn-btn-quiet {
    background: rgba(255, 255, 255, .65);
    border-color: var(--cairn-edge);
    color: var(--cairn-ink);
}

.cairn-btn-quiet:hover {
    border-color: var(--cairn-stone);
    color: var(--cairn-ink);
}

/* ---- the content surface ----
 *
 * The parchment has an engraving on it, and body text laid straight over the
 * ruled lines of Westminster is readable but tiring. So the page's content sits
 * on a wash of the same parchment: enough opacity to settle the text down,
 * little enough that the artwork still shows through and the page does not turn
 * into a white box on a picture.
 *
 * The home page is the exception — it is built as an open screen with its own
 * panels, and boxing the poster would undo it.
 */

main.container {
    background: rgba(246, 242, 233, .78);
    border: 1px solid var(--cairn-edge);
    border-radius: 6px;
    padding: 2rem;
    box-shadow: 0 10px 34px rgba(43, 43, 40, .07);
}

/* The home page is built as an open screen with its own panels, and the auth
   pages are a card on an empty page — a frame around either is a box around a
   box. */
main.container:has(> .cairn-home),
main.container:has(> .auth-page) {
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
}

@media (max-width: 575.98px) {
    /* A hair of parchment down each side, so the panel reads as a sheet laid on
       the page rather than as the page itself. */
    main.container {
        width: auto;
        margin-left: 3px;
        margin-right: 3px;
        padding: 1.25rem 1rem;
    }
}

/* The blog theme stretches every button to the full width of a phone. It makes
   "Send" look like a page section, and it is not what any of these forms want:
   the ones that really are full width say so with .w-100 in the markup. */
@media (max-width: 767.98px) {
    .btn {
        width: auto;
    }

    .btn.w-100 {
        width: 100% !important;
    }
}

/* ---- the footer ----
 * The blog theme made it a grey slab, which over parchment reads as a hole in
 * the page rather than as the end of it. */

.cairn-footer {
    margin-top: 3rem;
    padding: 2.5rem 0 2rem;
    border-top: 1px solid var(--cairn-edge);
    background: rgba(246, 242, 233, .78);
    color: var(--cairn-stone);
}

.cairn-footer a {
    color: var(--cairn-stone);
    text-decoration: none;
}

.cairn-footer a:hover {
    color: var(--cairn-ink);
    text-decoration: underline;
}

.cairn-footer-top {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 2rem 3rem;
}

.cairn-footer-brand {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    max-width: 26rem;
}

.cairn-footer-mark img {
    width: 64px;
    height: 64px;
    border-radius: 50%;
}

/* Outranks `.cairn-footer a`, which would otherwise grey the name out. */
.cairn-footer .cairn-footer-name {
    display: block;
    font-family: var(--cairn-font-display);
    font-size: 1.6rem;
    line-height: 1.1;
    color: var(--cairn-ink);
}

.cairn-footer-name:hover {
    text-decoration: none;
}

.cairn-footer-tagline {
    font-size: .75rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
    margin-top: .15rem;
}

.cairn-footer-losung {
    margin: .75rem 0 0;
    font-size: .95rem;
}

.cairn-footer-links {
    display: flex;
    gap: 3rem;
}

.cairn-footer-links div {
    display: flex;
    flex-direction: column;
    gap: .4rem;
}

.cairn-footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--cairn-edge);
}

.cairn-footer-social {
    display: flex;
    align-items: center;
    gap: .35rem;
}

.cairn-footer-social a {
    display: inline-flex;
    padding: .35rem;
    opacity: .55;
}

.cairn-footer-social a:hover {
    opacity: 1;
}

/* The icons are flat-filled SVGs from a stock set; without this they are pure
   black on parchment, which is the only truly black thing on the page. */
.cairn-footer-social svg {
    fill: var(--cairn-ink);
}

.cairn-footer-legal {
    font-size: .85rem;
    text-align: right;
}

@media (max-width: 767.98px) {
    /* Wrapped under the brand, the two columns were sized by their longest
       link and left a ragged gap down the right. Give them half the width
       each and they line up. */
    .cairn-footer-links {
        flex: 1 1 100%;
        gap: 1rem;
    }

    .cairn-footer-links div {
        flex: 1 1 0;
        min-width: 0;
    }

    .cairn-footer-legal {
        text-align: left;
    }
}

/* ---- the first-visit explainer ---- */

.cairn-explainer {
    background: rgba(246, 242, 233, .9);
    border: 1px solid var(--cairn-edge);
    border-radius: 6px;
    padding: 1.5rem;
    margin-bottom: 2rem;
}

.cairn-explainer .lead {
    margin-bottom: 0;
}

.cairn-steps {
    list-style: none;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin: 1rem 0 0;
}

.cairn-steps li {
    flex: 1 1 12rem;
    color: var(--cairn-stone);
}

.cairn-steps span {
    display: inline-block;
    width: 1.6rem;
    height: 1.6rem;
    line-height: 1.6rem;
    text-align: center;
    border-radius: 50%;
    background: var(--cairn-ink);
    color: #fff;
    margin-right: .5rem;
}

/* ---- the home page ----
 *
 * The first screen carries one image and the state picks it: the quest's own
 * illustration when there is something to play, the poster when there is not.
 * Everything else — the explainer, yesterday, the archive — starts below the
 * fold, because the button is what the visit is for.
 */

/* No 40px gap between the bar and a screen that is meant to fill the window. */
main.container:has(> .cairn-home) {
    margin-top: 0;
}

.cairn-screen {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 2rem 0 2.5rem;
    /* Fills a laptop screen, and stops there: on a tall monitor an uncapped
       100vh leaves the quest marooned in the middle of an empty page. */
    min-height: calc(100vh - var(--cairn-bar-h));
    min-height: min(calc(100svh - var(--cairn-bar-h)), 52rem);
}

/* A: live and unsolved. Picture on one side, the question and the button on
   the other, both centred on the fold. */
.cairn-screen.cairn-live {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
    align-content: center;
}

.cairn-screen.cairn-live-nopic {
    display: flex;
    text-align: center;
}

.cairn-live-art {
    margin: 0;
}

.cairn-live-art img {
    width: 100%;
    max-height: 62vh;
    object-fit: cover;
    background: #fff;
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    box-shadow: 0 14px 40px rgba(43, 43, 40, .18);
}

.cairn-live-title {
    font-family: var(--cairn-font-display);
    font-size: clamp(2rem, 4.2vw, 3rem);
    line-height: 1.1;
    margin: 0 0 .75rem;
}

.cairn-live-words .cairn-year {
    margin-bottom: 1rem;
}

.cairn-live-nopic .cairn-year {
    justify-content: center;
}

/* Three lines of scene-setting and no more: the story is the quest page's job,
   and a long paragraph here pushes the button off the screen. */
.cairn-live-words .cairn-scene {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cairn-live-words .cairn-question {
    font-size: 1.25rem;
    font-weight: 600;
}

.cairn-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-top: 1.25rem;
    color: var(--cairn-stone);
}

.cairn-meta .cairn-counter,
.cairn-meta .cairn-streak {
    margin-top: 0;
}

/* B: live and already solved. */
.cairn-screen.cairn-solved {
    align-items: center;
}

.cairn-result-card {
    max-width: 38rem;
    padding: 2.5rem;
    text-align: center;
}

.cairn-result-card h1 {
    font-family: var(--cairn-font-display);
}

/* The quest page has its own, smaller .cairn-score; this is the home page's
   result, where the number is the whole point of the card. */
.cairn-result-card .cairn-score {
    font-family: var(--cairn-font-display);
    font-size: 3.5rem;
    font-weight: 400;
    line-height: 1;
    color: var(--cairn-found);
    margin: .75rem 0 1.25rem;
}

.cairn-result-card .cairn-score span {
    display: block;
    margin-top: .5rem;
    font-family: var(--cairn-font-text);
    font-size: .8rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-result-place {
    margin-top: 1.25rem;
}

/* C: nothing live. The poster is the page. */
.cairn-screen.cairn-poster-screen {
    align-items: center;
    text-align: center;
}

.cairn-poster {
    max-width: min(100%, 62rem);
    max-height: 58vh;
    width: auto;
    height: auto;
    border: 1px solid var(--cairn-edge);
    border-radius: 6px;
    box-shadow: 0 18px 50px rgba(43, 43, 40, .18);
}

.cairn-poster-foot {
    margin-top: 1.75rem;
}

/* The same poster below a live quest, where it is the second thing on the page
   rather than the whole of it: smaller, and given room to read as a break
   rather than as more quest. */
.cairn-intro {
    margin: 4.5rem 0 3rem;
    text-align: center;
}

/* Wide enough to be looked at rather than glanced past. Sized by width, not by
   viewport height — a height cap here would quietly undo the width on any short
   window, since the image keeps its ratio. */
.cairn-intro .cairn-poster {
    width: 80%;
    max-width: 80%;
    max-height: none;
}

.cairn-intro-text {
    max-width: 40rem;
    margin: 1.5rem auto 0;
    font-family: var(--cairn-font-display);
    font-size: 1.25rem;
    color: var(--cairn-stone);
}

.cairn-next-label {
    margin: 0;
    font-size: .8rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-poster-foot .cairn-countdown {
    font-family: var(--cairn-font-display);
    font-size: 1.8rem;
    color: var(--cairn-ink);
    margin: .25rem 0 0;
}

.cairn-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 1.5rem;
}

/* Side by side, so they have to be the same height. */
.cairn-actions .cairn-btn-quiet {
    font-size: 1.15rem;
    padding: .85rem 1.6rem;
}

.cairn-poster-screen .cairn-actions,
.cairn-result-card .cairn-actions {
    justify-content: center;
}

.cairn-card-wide {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .75rem;
}

.cairn-card-wide strong,
.cairn-card-wide span {
    display: inline;
}

@media (max-width: 767.98px) {
    /* One column, and the picture gives up most of its height: on a phone the
       button matters more than the engraving. */
    .cairn-screen.cairn-live {
        display: flex;
        text-align: center;
    }

    .cairn-live-art img {
        max-height: 30vh;
    }

    .cairn-meta,
    .cairn-actions,
    .cairn-live-words .cairn-year {
        justify-content: center;
    }

    .cairn-poster {
        max-height: 44vh;
    }

    /* On a phone 80% is just a smaller picture with margins either side. */
    .cairn-intro .cairn-poster {
        width: 100%;
        max-width: 100%;
    }

    .cairn-btn-play {
        display: block;
        text-align: center;
    }
}

/* ---- the quest page's hero ---- */

.cairn-hero {
    text-align: center;
    padding: 2rem 0;
}

.cairn-hero-image {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
    margin-bottom: 1rem;
}

.cairn-scene {
    font-family: var(--cairn-font-text);
    font-size: 1.2rem;
    font-style: italic;
    color: var(--cairn-stone);
}

/* The year. It never leaves the screen — it is the spine of the puzzle, the
   thing that turns a whole country into a shortlist — so it is set large and
   unmissable rather than as a caption. */
.cairn-year {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-family: var(--cairn-font-display);
    font-size: 2rem;
    line-height: 1.1;
    letter-spacing: .04em;
    color: var(--cairn-found);
}

/* "793" on its own is a number nobody can place. */
.cairn-year-label {
    font-family: var(--cairn-font-text);
    font-size: .8rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-question {
    font-size: 1.15rem;
    margin: 1rem 0;
}

.cairn-scene-block {
    margin-bottom: 1.5rem;
}

.cairn-scene-image {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
    margin-bottom: 1rem;
}

.cairn-hint-preview {
    border-left: 3px solid var(--cairn-edge);
    padding-left: 1rem;
    margin: 1.5rem auto;
    max-width: 34rem;
    text-align: left;
    font-family: "Playfair Display", Georgia, serif;
}

.cairn-countdown {
    font-size: 1.4rem;
    color: var(--cairn-stone);
}

.cairn-counter,
.cairn-streak {
    color: var(--cairn-stone);
    margin-top: 1rem;
}

.cairn-section {
    margin: 3rem 0;
}

.cairn-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    gap: 1rem;
}

.cairn-card {
    display: block;
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: 1rem;
    text-decoration: none;
    color: inherit;
    background: rgba(255, 255, 255, .72);
}

.cairn-card:hover {
    border-color: var(--cairn-stone);
}

.cairn-card img {
    max-width: 100%;
    height: auto;
    border-radius: 3px;
    margin-bottom: .5rem;
}

.cairn-card strong,
.cairn-card span {
    display: block;
}

.cairn-played {
    color: var(--cairn-found);
    font-size: .9rem;
}

/* ---- the quest page ---- */

.cairn-quest-header {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: 1rem;
}

.cairn-quest-header h1 {
    font-family: var(--cairn-font-display);
    margin: 0;
    /* Blackletter and uncial need room to breathe, and they run small for
       their point size next to a humanist face. */
    line-height: 1.25;
}

.cairn-hint {
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: 1rem;
    margin-bottom: 1rem;
    background: var(--cairn-parchment);
}

.cairn-hint-locked {
    background: #fff;
    border-style: dashed;
}

.cairn-hint-number {
    font-size: .75rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
    margin-bottom: .5rem;
}

.cairn-hint-image {
    max-width: 100%;
    height: auto;
    border-radius: 3px;
    margin-bottom: .75rem;
}

.cairn-hint-text {
    font-family: "Playfair Display", Georgia, serif;
    font-size: 1.1rem;
    margin: 0;
}

.cairn-hint-credit {
    margin: .5rem 0 0;
}

.cairn-first-sight {
    font-family: "Playfair Display", Georgia, serif;
    font-size: 1.1rem;
    color: var(--cairn-found);
}

.cairn-credits {
    list-style: none;
    padding: 0;
}

.cairn-checkpoint-help {
    margin-top: .5rem;
}

.cairn-scorebar {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    padding: .5rem 0;
    color: var(--cairn-stone);
}

/* ---- the playing frame ----
   Only on /quest/{id}, which uses _outer/quest.htm. Everything here exists to
   give the map the screen: the site's two rows of navigation and its footer are
   right for a page you read and wrong for the one screen where the game
   happens. */

.cairn-playing {
    --cairn-topbar: 3.25rem;
    margin: 0;
    /* A column that owns the viewport, with the stage taking whatever the bar
       and any flash message leave. Measuring instead — 100vh minus a hard-coded
       bar height — is right until something appears above the stage that the
       arithmetic never heard of, and then the map is a few pixels too tall and
       the page gains a scrollbar it should not have. */
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.cairn-quest-main {
    flex: 1;
    /* Without this a flex child refuses to shrink below its content, which is
       how an overflow:auto pane ends up not scrolling. */
    min-height: 0;
}

.cairn-quest-main > .cairn-quest {
    height: 100%;
}

.cairn-slim-bar {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    height: var(--cairn-topbar);
    padding: 0 1rem;
    border-bottom: 1px solid var(--cairn-edge);
    background: #fff;
}

.cairn-slim-brand {
    font-family: "Playfair Display", Georgia, serif;
    font-size: 1.25rem;
    color: var(--cairn-ink);
    text-decoration: none;
}

.cairn-slim-nav {
    display: flex;
    gap: 1.25rem;
    flex: 1;
    flex-wrap: wrap;
    overflow: hidden;
}

.cairn-slim-nav a {
    color: var(--cairn-stone);
    text-decoration: none;
    white-space: nowrap;
}

.cairn-slim-nav a:hover {
    color: var(--cairn-ink);
}

.cairn-focus-toggle {
    border: 1px solid var(--cairn-edge);
    background: #fff;
    border-radius: 4px;
    padding: .25rem .75rem;
    color: var(--cairn-stone);
    white-space: nowrap;
}

.cairn-focus-toggle:hover {
    color: var(--cairn-ink);
    border-color: var(--cairn-stone);
}

/* The way out of focus mode. It cannot cost a permanent strip of screen — that
   is the whole point of focus mode — so it sits in the corner at low contrast
   and comes up on hover or on keyboard focus. Escape works too. */
.cairn-focus-escape {
    display: none;
    position: fixed;
    top: .5rem;
    right: .5rem;
    z-index: 1200;
    width: 2rem;
    height: 2rem;
    line-height: 1;
    font-size: 1.25rem;
    border: 1px solid var(--cairn-edge);
    border-radius: 50%;
    background: rgba(255, 255, 255, .75);
    color: var(--cairn-stone);
    opacity: .35;
    transition: opacity .15s;
}

.cairn-focus-escape:hover,
.cairn-focus-escape:focus {
    opacity: 1;
}

body.cairn-focus .cairn-slim-bar {
    display: none;
}

body.cairn-focus .cairn-focus-escape {
    display: block;
}

body.cairn-focus {
    --cairn-topbar: 0rem;
}

/* Rail and map. They scroll independently: the story is long and the map must
   not travel with it. */
.cairn-stage {
    display: grid;
    grid-template-columns: 1fr;
    height: 100%;
}

.cairn-rail {
    overflow-y: auto;
    /* The rail is a fixed column, so anything a shade too wide — a long word, a
       list's default indent — buys it a horizontal scrollbar it can never
       usefully use. */
    overflow-x: hidden;
    padding: 0 1.25rem 1.25rem;
}

.cairn-rail .cairn-guess-log {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
}

.cairn-rail .cairn-guess-log li {
    border-left: 3px solid var(--cairn-edge);
    padding-left: .75rem;
    margin-bottom: .75rem;
}

/* The year sticks to the top of the rail. Everything else here can scroll
   away; the year cannot, because the whole puzzle is built on it being on
   screen from the first second to the last. */
.cairn-rail .cairn-quest-header {
    position: sticky;
    top: 0;
    z-index: 5;
    background: #fff;
    padding: 1rem 0 .75rem;
    margin-bottom: 0;
    border-bottom: 1px solid var(--cairn-edge);
}

/* Once it is stuck to the top of a 400px rail, the quest number is noise
   between the title and the story. */
.cairn-rail .cairn-quest-number {
    display: none;
}

.cairn-mapwrap {
    position: relative;
    min-height: 20rem;
}

@media (min-width: 992px) {
    .cairn-stage {
        /* Wide enough for a hint panel to read as a paragraph rather than a
           column of two-word lines, and no wider — the rest is map. */
        grid-template-columns: minmax(20rem, 25rem) 1fr;
    }

    .cairn-rail {
        border-right: 1px solid var(--cairn-edge);
    }
}

/* Anything sitting on the map. Leaflet's own controls are at z-index 800 and
   its popups at 700, so these have to clear both. */
.cairn-over-map {
    position: absolute;
    z-index: 900;
    background: rgba(255, 255, 255, .92);
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: .4rem .75rem;
    backdrop-filter: blur(2px);
}

.cairn-scorebar.cairn-over-map {
    top: .75rem;
    right: .75rem;
    gap: 1rem;
}

.cairn-controls.cairn-over-map {
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: .75rem;
    /* One row. Two rows of floating chrome eat more map than the give-up link
       is worth, and the bar jumping taller as the help text changes length is
       movement over a map somebody is reading. */
    flex-wrap: nowrap;
    white-space: nowrap;
    max-width: calc(100% - 2rem);
    padding: .4rem .5rem .4rem .4rem;
}

.cairn-controls.cairn-over-map .btn-link {
    padding-left: .25rem;
    padding-right: .25rem;
    font-size: .875rem;
}

#cairn-map-help {
    font-size: .875rem;
    /* A coordinate readout is fixed-width by nature; the tabular figures stop
       the bar twitching as the numbers change under a dragging thumb. */
    font-variant-numeric: tabular-nums;
}

/* Honest, not alarming: the point is that a guest knows the deal before it
   costs them anything, not that they are nagged on every screen. */
.cairn-guest-note {
    font-size: .8rem;
    line-height: 1.45;
    color: var(--cairn-stone);
    background: var(--cairn-parchment);
    border-radius: 4px;
    padding: .6rem .75rem;
    margin-bottom: 1rem;
}

.cairn-log-label {
    display: block;
    font-size: .7rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

/* The map has to have a height in CSS: Leaflet measures its container, and a
   container with no height renders a map one pixel tall. Inside the stage it
   fills its cell instead of standing at a fixed height. */
.cairn-mapwrap .cairn-map {
    position: absolute;
    inset: 0;
    height: 100%;
    border: 0;
    border-radius: 0;
}

.cairn-map {
    height: 32rem;
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
}

.cairn-map-small {
    height: 20rem;
    margin: 1.5rem 0;
}

@media (max-width: 991px) {
    .cairn-map {
        height: 22rem;
    }
}

.cairn-controls {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: .75rem 0;
    flex-wrap: wrap;
}

.cairn-guess-log {
    list-style: none;
    padding: 0;
    margin: 0;
}

.cairn-guess-log li {
    padding: .35rem 0;
    border-bottom: 1px solid var(--cairn-edge);
    color: var(--cairn-warm);
}

.cairn-guess-correct {
    color: var(--cairn-found);
    font-weight: 600;
}

.cairn-reveal {
    border-top: 3px solid var(--cairn-ink);
    padding-top: 1rem;
    margin-top: 1.5rem;
}

.cairn-score {
    font-size: 2rem;
    font-weight: 700;
    color: var(--cairn-found);
    margin: 0;
}

.cairn-signup-prompt {
    background: #fff;
    border: 1px dashed var(--cairn-edge);
    border-radius: 4px;
    padding: .75rem 1rem;
}

/* ---- lists and boards ---- */

.cairn-filter {
    max-width: 18rem;
    margin: 1rem 0 2rem;
}

.cairn-pagination {
    display: flex;
    gap: 1.5rem;
    align-items: center;
    margin: 2rem 0;
}

.cairn-board td,
.cairn-board th {
    vertical-align: middle;
}

.cairn-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    margin: 1.5rem 0;
}

.cairn-stat {
    text-align: center;
}

.cairn-stat-value {
    display: block;
    font-size: 2rem;
    font-weight: 700;
    font-family: "Playfair Display", Georgia, serif;
}

.cairn-stat-label {
    display: block;
    font-size: .8rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-place-list {
    list-style: none;
    padding: 0;
    columns: 2;
}

.cairn-place-list li {
    break-inside: avoid;
    padding: .3rem 0;
}

@media (max-width: 767px) {
    .cairn-place-list {
        columns: 1;
    }
}

.cairn-place-meta {
    color: var(--cairn-stone);
}

.cairn-pipeline {
    background: var(--cairn-parchment);
    border: 1px solid var(--cairn-edge);
    padding: 1rem;
    border-radius: 4px;
}

/* ---- the editor's frame ---- */

.cairn-admin-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    border-bottom: 2px solid var(--cairn-ink);
    padding: 1rem 0;
    margin-bottom: 1.5rem;
}

.cairn-admin-brand strong {
    font-family: "Playfair Display", Georgia, serif;
    font-size: 1.3rem;
    margin-right: .5rem;
}

.cairn-admin-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}

.cairn-admin-nav a {
    color: var(--cairn-stone);
    text-decoration: none;
}

.cairn-admin-nav a:hover,
.cairn-admin-nav a.active {
    color: var(--cairn-ink);
    text-decoration: underline;
}

/* ---- the quest builder ---- */

.cairn-build-form {
    max-width: 46rem;
}

.cairn-quest-form fieldset {
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: 1rem 1.25rem;
    background: #fff;
}

.cairn-quest-form legend {
    font-family: "Playfair Display", Georgia, serif;
    width: auto;
    padding: 0 .5rem;
}

.cairn-panel-edit {
    border-left: 3px solid var(--cairn-edge);
    padding-left: 1rem;
    margin-bottom: 1.5rem;
}

.cairn-picture {
    background: var(--cairn-parchment);
    border-radius: 4px;
    padding: .75rem;
    margin-bottom: .5rem;
}

.cairn-picture-preview img {
    max-width: 100%;
    height: auto;
    border-radius: 3px;
}

/* A placeholder with a real height, so generating a picture does not make the
   whole form jump a screen's worth when it arrives. */
.cairn-picture-placeholder {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    align-items: center;
    justify-content: center;
    height: 8rem;
    border: 1px dashed var(--cairn-edge);
    border-radius: 3px;
    background: #fff;
}

/* Drawing a panel takes the better part of a minute, which is long enough that
   a line of text changing is easy to miss and easy to read as "nothing
   happened". Its own spinner rather than Bootstrap's, so the one visible sign
   that the builder is working does not depend on a CDN class name. */
.cairn-spinner {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -.125em;
    border: 2px solid var(--cairn-edge);
    border-top-color: var(--cairn-stone);
    border-radius: 50%;
    animation: cairn-spin .7s linear infinite;
}

.cairn-spinner-lg {
    width: 1.75rem;
    height: 1.75rem;
    border-width: 3px;
}

@keyframes cairn-spin {
    to { transform: rotate(360deg); }
}

/* Someone who has asked not to be shown motion still needs to know the thing
   is working, so it pulses instead of turning. */
@media (prefers-reduced-motion: reduce) {
    .cairn-spinner {
        animation: cairn-pulse 1.4s ease-in-out infinite;
    }

    @keyframes cairn-pulse {
        50% { opacity: .25; }
    }
}

/* The conversation sticks while the form scrolls: the two halves of this screen
   are read against each other, and a chat that scrolls away is a chat nobody
   uses. */
.cairn-chat {
    position: sticky;
    top: 1rem;
}

.cairn-chat-log {
    height: 26rem;
    overflow-y: auto;
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: .75rem;
    background: #fff;
    margin-bottom: .75rem;
}

.cairn-chat-line {
    margin-bottom: .75rem;
}

.cairn-chat-line p {
    margin: 0;
}

.cairn-chat-who {
    display: block;
    font-size: .7rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--cairn-stone);
}

.cairn-chat-user p {
    background: var(--cairn-parchment);
    border-radius: 4px;
    padding: .5rem .75rem;
}

.cairn-chat-error p {
    color: #a4342c;
}

.cairn-preview,
.cairn-preview-admin {
    border: 1px solid var(--cairn-edge);
    border-radius: 4px;
    padding: 1.25rem;
    background: #fff;
}
