/* The globe is the page; everything else floats over it and stays out of the way. */

:root {
    --ink: #e6ecea;
    --muted: #8798a0;
    --line: rgba(150, 175, 190, 0.18);
    --panel: rgba(10, 15, 20, 0.72);
    --accent: #ffd166;
    /* Three roles, not two. The whole interface was previously monospace, which is a terminal
       aesthetic rather than a decision, and it meant swapping one clean mono for another changed
       almost nothing on screen.

       Display is a condensed grotesque because that is what maps set place names in. Text is a
       proper UI face for anything meant to be read. Mono is kept for what it is actually good at:
       coordinates, cell ids and columns of figures that need to line up.

       Each keeps a fallback with matching proportions, so a font that fails to load degrades
       instead of reflowing the page. */
    --sans: "Archivo Narrow", "Arial Narrow", "Helvetica Neue Condensed", sans-serif;
    --text: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
    --mono: "Azeret Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

* {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
}

body {
    margin: 0;
    background: #05080c;
    color: var(--ink);
    font-family: var(--text);
    font-size: 14px;
    overflow: hidden;
    -webkit-font-smoothing: antialiased;
}

#map {
    position: fixed;
    inset: 0;
}

/* MapLibre's own chrome, toned down to match the panel rather than its default light look. */
.maplibregl-ctrl-group {
    background: var(--panel) !important;
    border: 1px solid var(--line);
    box-shadow: none !important;
}

.maplibregl-ctrl-group button+button {
    border-top: 1px solid var(--line);
}

.maplibregl-ctrl-group button .maplibregl-ctrl-icon {
    filter: invert(1) opacity(.75);
}

.maplibregl-ctrl-attrib {
    background: rgba(6, 10, 14, .7) !important;
    color: var(--muted);
    font-family: var(--text);
    font-size: .62rem;
}

.maplibregl-ctrl-attrib a {
    color: var(--muted);
}

.maplibregl-canvas {
    outline: none;
}

/* --- chrome ------------------------------------------------------------------------- */

.topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.15rem clamp(1rem, 3vw, 2rem);
    pointer-events: none;
}

.topbar>* {
    pointer-events: auto;
}

.brand {
    display: flex;
    align-items: center;
    gap: .6rem;
}

.mark {
    width: 12px;
    height: 12px;
    border: 1.5px solid var(--accent);
    border-radius: 2px;
    box-shadow: 0 0 12px rgba(255, 209, 102, .5);
}

.wordmark {
    font-family: var(--sans);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.topbar-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.stat {
    color: var(--muted);
    font-size: .78rem;
    letter-spacing: .04em;
}

.btn {
    font-family: var(--text);
    font-size: .8rem;
    letter-spacing: .05em;
    color: #06090c;
    background: var(--accent);
    border: 0;
    border-radius: 2px;
    padding: .55rem .95rem;
    cursor: pointer;
    transition: filter .15s ease;
}

.btn:hover {
    filter: brightness(1.1);
}

.btn:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

.btn.ghost {
    /* The topbar floats over the globe with no ground of its own, so a transparent button was
       legible over ocean and invisible over the ice caps. The panel tone rather than a new colour,
       so the controls and the panel read as the same surface. */
    background: var(--panel);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: var(--ink);
    border: 1px solid var(--line);
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.btn.ghost:hover {
    background: rgba(18, 26, 34, 0.82);
    border-color: rgba(150, 175, 190, 0.32);
    filter: none;
}

/* --- panel -------------------------------------------------------------------------- */

.sheet-grip {
    display: none;
}

.panel {
    position: fixed;
    top: 4.6rem;
    left: clamp(1rem, 3vw, 2rem);
    width: min(340px, calc(100vw - 2rem));
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.1rem;
    background: var(--panel);
    backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: 4px;
}

.search {
    display: flex;
    gap: .5rem;
}

.search input {
    flex: 1;
    min-width: 0;
    font-family: var(--text);
    font-size: .82rem;
    color: var(--ink);
    background: rgba(255, 255, 255, .05);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: .55rem .7rem;
}

.search input::placeholder {
    color: var(--muted);
}

.search input:focus {
    outline: none;
    border-color: var(--accent);
}

.status {
    font-size: .8rem;
    line-height: 1.5;
    color: var(--muted);
}

.hidden {
    display: none !important;
}

.eyebrow {
    margin: 0;
    font-size: .66rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted);
}

.holding,
.inspect {
    display: flex;
    flex-direction: column;
    gap: .85rem;
    padding-top: .9rem;
    border-top: 1px solid var(--line);
}

.addr,
.coords {
    margin: .25rem 0 0;
    font-family: var(--sans);
    font-weight: 600;
    font-size: 1.15rem;
    letter-spacing: .02em;
}

.figures,
.kv {
    margin: 0;
    display: grid;
    gap: .7rem;
    font-variant-numeric: tabular-nums;
}

.figures {
    grid-template-columns: 1fr 1fr;
}

.figures>div,
.kv>div {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}

.figures dt,
.kv dt {
    font-size: .64rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--muted);
}

.figures dd {
    margin: 0;
    font-size: 1.05rem;
}

.kv dd {
    margin: 0;
    font-size: .78rem;
    overflow-wrap: anywhere;
}

.parcels {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.parcel {
    width: 100%;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    font-family: var(--text);
    font-size: .78rem;
    color: var(--ink);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 2px;
    padding: .4rem .5rem;
    cursor: pointer;
    text-align: left;
}

.parcel:hover {
    background: rgba(255, 255, 255, .06);
    border-color: var(--line);
}

.parcel-size {
    font-family: var(--mono);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.inspect-actions {
    display: flex;
    gap: .5rem;
}

.credits {
    position: fixed;
    bottom: .75rem;
    right: clamp(1rem, 3vw, 2rem);
    font-size: .66rem;
    color: var(--muted);
    opacity: .75;
    pointer-events: none;
}

@media (max-width: 720px) {
    /* A phone has no room for a floating card beside the map, so the panel becomes a sheet: it
       sits on the bottom edge, opens to most of the screen, and is pushed away when it is in the
       way. The map is the page, and the sheet has to be able to get out of its light. */
    .panel {
        top: auto;
        bottom: 0;
        left: 0;
        right: 0;
        width: auto;
        max-height: 88vh;
        padding: .35rem 1rem calc(1.1rem + env(safe-area-inset-bottom));
        border-radius: 16px 16px 0 0;
        border-bottom: 0;
        gap: .85rem;
        transform: translateY(var(--sheet-y, 0));
        touch-action: pan-y;
    }

    /* Only while a finger is on it. Otherwise the snap back should be animated. */
    .panel.dragging {
        transition: none;
    }

    .panel:not(.dragging) {
        transition: transform .26s cubic-bezier(.22, .8, .3, 1);
    }

    /* Pushed away. Left on the edge rather than gone, so it can be pulled back without hunting
       for a button. */
    .panel.dismissed {
        transform: translateY(calc(100% - 2.1rem));
    }

    .sheet-grip {
        display: block;
        flex: 0 0 auto;
        align-self: center;
        width: 2.4rem;
        height: 4px;
        margin: .3rem 0 .1rem;
        border-radius: 100px;
        background: var(--line-strong, rgba(150, 175, 190, .45));
        cursor: grab;
    }

    .credits {
        display: none;
    }

    .topbar {
        padding: .7rem .75rem;
        gap: .55rem;
    }

    /* The brand holds its width; the controls take what is left and scroll inside it. Left to
       wrap, they pushed the row wider than the screen and the last buttons went off the edge
       with no way to reach them. */
    .brand {
        flex: 0 0 auto;
    }

    .topbar-actions {
        gap: .35rem;
        min-width: 0;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .topbar-actions::-webkit-scrollbar {
        display: none;
    }

    .topbar-actions .btn {
        padding: .45rem .7rem;
        font-size: .75rem;
        white-space: nowrap;
        flex: 0 0 auto;
    }

    /* The supply is in the panel and on the about page. At this width the topbar cannot say it
       too without landing on the wordmark. */
    .topbar .stat {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    * {
        transition: none !important;
    }
}

/* --- cell card ---------------------------------------------------------------------- */

.card {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.card canvas {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    background: #0b1220;
    border: 1px solid var(--line);
    border-radius: 2px;
    /* The cell is the frame, so no cropping and no letterboxing. */
    object-fit: cover;
}

.card figcaption {
    font-size: .7rem;
    line-height: 1.45;
    color: var(--muted);
}

.card figcaption b {
    color: var(--ink);
    font-weight: 500;
}

.zoomstat {
    font-size: .72rem;
    opacity: .8;
    font-variant-numeric: tabular-nums;
}

/* Off is dimmer type, not a dimmer button. Fading the whole element also faded the ground it
   needs, which put it back to being unreadable over bright imagery — the problem the ground was
   added to solve. */
.btn.ghost[aria-pressed="false"] {
    color: var(--muted);
    border-color: rgba(150, 175, 190, 0.1);
}

/* --- city labels -------------------------------------------------------------------- */

/* Three layers, stated in one place because they were previously implicit and got it wrong:
   the label layer was the only positioned element with a z-index, so place names painted over
   the panel and the toolbar rather than sliding under them.

     0  the map canvas
     1  place names, which belong to the map and move with it
     2  the interface: toolbar, panel, credits */
.places {
    position: fixed;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 1;
}

.topbar,
.panel,
.credits {
    z-index: 2;
}

.place {
    position: absolute;
    top: 0;
    left: 0;
    white-space: nowrap;
    font-family: var(--sans);
    font-size: .78rem;
    font-weight: 500;
    letter-spacing: .04em;
    color: rgba(255, 255, 255, .92);
    /* A halo rather than a box, so the label sits on the imagery without covering it. */
    text-shadow:
        0 0 3px rgba(0, 0, 0, .95),
        0 0 7px rgba(0, 0, 0, .8),
        0 1px 2px rgba(0, 0, 0, .9);
    will-change: transform, opacity;
}

/* A country names an area, not a point, so it is set the way an area label is set on a printed
   map: letter-spaced caps, a little smaller than the city names and a little quieter, so it reads
   as the ground you are over rather than as another place to go. The warm tint ties it to the
   border lines, which are the other half of the same political layer. */
.place.country {
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: rgba(255, 217, 160, .82);
}

.place.capital {
    font-weight: 700;
    letter-spacing: .06em;
    color: #fff;
}

.place.capital::before {
    content: "";
    display: inline-block;
    width: 4px;
    height: 4px;
    margin-right: .4em;
    vertical-align: middle;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 4px rgba(0, 0, 0, .9);
}

/* --- duel prototype ----------------------------------------------------------------- */

.play-page {
    overflow: auto;
    background:
        radial-gradient(1200px 600px at 50% -10%, rgba(77, 159, 214, .10), transparent 70%),
        #05080c;
}

.play-shell {
    max-width: 940px;
    margin: 0 auto;
    padding: 5.5rem 1.25rem 4rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.stat.score {
    font-size: 1rem;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.play-table {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1.25rem;
}

.play-versus {
    font-family: var(--sans);
    font-size: .8rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--muted);
}

.play-card {
    background: rgba(10, 15, 20, .72);
    border: 1px solid var(--line);
    border-radius: 4px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* The 123 landmark cells are the only truly scarce cards, so they get the only accent. */
.play-card.landmark {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px rgba(255, 209, 102, .25), 0 0 30px rgba(255, 209, 102, .12);
}

.play-card header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    padding: .8rem .9rem;
    border-bottom: 1px solid var(--line);
}

.play-card h3 {
    margin: 0;
    font-family: var(--sans);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.play-tier {
    font-size: .66rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
}

.play-thumb {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    background: #0b1220;
}

.play-thumb.blank {
    background:
        repeating-linear-gradient(45deg, rgba(255, 255, 255, .03) 0 10px, transparent 10px 20px),
        #0b1220;
}

.play-stats {
    margin: 0;
    padding: .4rem .9rem .8rem;
}

.stat-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .3rem 0;
    font-size: .8rem;
    border-bottom: 1px solid rgba(150, 175, 190, .08);
}

.stat-row:last-child {
    border-bottom: 0;
}

.stat-row dt {
    color: var(--muted);
}

.stat-row dd {
    margin: 0;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

/* The stat that decided the round. */
.stat-row.lit {
    color: var(--accent);
}

.stat-row.lit dt {
    color: var(--accent);
}

.play-log {
    margin: 0;
    min-height: 1.4em;
    font-size: .9rem;
    color: var(--ink);
}

.play-calls {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.play-note {
    margin: 1rem 0 0;
    max-width: 62ch;
    font-size: .78rem;
    line-height: 1.6;
    color: var(--muted);
}

@media (max-width: 640px) {
    .play-table {
        grid-template-columns: 1fr;
    }

    .play-versus {
        text-align: center;
    }
}

.play-contains {
    margin: 0;
    padding: .45rem .9rem;
    font-size: .72rem;
    color: var(--muted);
    border-bottom: 1px solid var(--line);
}

.play-power {
    margin: 0;
    padding: .55rem .9rem .7rem;
    font-size: .74rem;
    line-height: 1.45;
    color: var(--accent);
    border-top: 1px solid var(--line);
}

.play-note-inline {
    color: var(--accent);
}

/* --- collection and hand ------------------------------------------------------------- */

.play-collection,
.play-hand {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .75rem;
}

.play-hand-wrap {
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.pick {
    cursor: pointer;
}

.play-card.small .play-thumb {
    aspect-ratio: 16 / 10;
}

.play-card.small header {
    padding: .55rem .6rem;
}

.play-card.small h3 {
    font-size: .82rem;
}

.play-card.small .play-stats {
    padding: .25rem .6rem .5rem;
}

.play-card.small .stat-row {
    font-size: .7rem;
    padding: .2rem 0;
}

.play-card.small .play-power,
.play-card.small .play-contains {
    font-size: .66rem;
    padding: .4rem .6rem;
}

/* Chosen for the deck. */
.play-card.picked {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}

.pick:hover .play-card {
    border-color: var(--accent);
}

.play-slot {
    display: grid;
    place-items: center;
    min-height: 180px;
    border: 1px dashed var(--line);
    border-radius: 4px;
    color: var(--muted);
    font-size: .78rem;
}

/* --- collection page ---------------------------------------------------------------------

   The map is a fixed viewport with panels floating over it; this page is a document that
   scrolls. `.doc` on the body switches between the two rather than the two pages carrying
   separate copies of the shell. */

.doc {
    overflow: auto;
    height: auto;
    min-height: 100%;
    background:
        radial-gradient(1200px 600px at 50% -10%, rgba(255, 209, 102, .06), transparent 70%),
        #05080c;
}

.doc .topbar {
    position: sticky;
    background: rgba(5, 8, 12, .82);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
    pointer-events: auto;
}

.sheet {
    max-width: 1220px;
    margin: 0 auto;
    padding: 2.5rem clamp(1rem, 3vw, 2rem) 4rem;
    display: flex;
    flex-direction: column;
    gap: 2.25rem;
}

.lookup h1 {
    margin: 0 0 .5rem;
    font-family: var(--sans);
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 700;
    letter-spacing: .01em;
    text-wrap: balance;
}

.lede {
    /* Running text wants a measure, whatever the container is doing. */
    max-width: 56ch;
    margin: 0 0 1.5rem;
    color: var(--muted);
    line-height: 1.55;
}

.search.wide {
    max-width: 520px;
}

/* --- summary --- */

.summary {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 2rem;
    padding: 1.4rem 1.5rem;
    border: 1px solid var(--line);
    border-radius: 3px;
    background: var(--panel);
}

.summary-head {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.summary .addr {
    margin: 0;
    font-family: var(--mono);
    font-size: 1.05rem;
    font-weight: 400;
}

.summary .figures {
    flex: 1;
    grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
    gap: 1.5rem;
}

/* --- toolbar --- */

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .9rem;
}

.toolbar-spacer {
    flex: 1;
}

.field {
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.field>span {
    font-family: var(--sans);
    font-size: .64rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted);
}

.field select {
    font-family: var(--text);
    font-size: .82rem;
    color: var(--ink);
    background: rgba(10, 15, 20, .9);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: .5rem .7rem;
    min-width: 12rem;
    cursor: pointer;
}

.field select:focus-visible,
.cell-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* --- the cells --- */

.cell-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
}

.cell-card {
    border: 1px solid var(--line);
    border-radius: 3px;
    background: var(--panel);
    overflow: hidden;
    transition: border-color .15s ease, transform .15s ease;
}

.cell-card:hover {
    border-color: rgba(255, 209, 102, .45);
    transform: translateY(-2px);
}

/* A landmark cell is one of 123 in 25 million, so it is worth seeing at a glance in a wall of
   cards — but as a warm edge rather than a badge shouting over the imagery. */
.cell-card.is-landmark {
    border-color: rgba(255, 209, 102, .38);
}

.cell-card.is-wonder {
    border-color: rgba(255, 209, 102, .75);
    box-shadow: inset 0 0 0 1px rgba(255, 209, 102, .22);
}

.cell-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.cell-thumb {
    aspect-ratio: 1;
    background: #0a1016;
}

.cell-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cell-body {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: .8rem .85rem .9rem;
}

.cell-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}

.cell-head h3 {
    margin: 0;
    font-family: var(--sans);
    font-size: .98rem;
    font-weight: 600;
    line-height: 1.25;
    /* Names run long — "Great Barrier Reef", "near Nizhny Novgorod" — and a card that grows to
       fit one breaks the grid rhythm for every card beside it. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cell-badge {
    flex: none;
    font-family: var(--sans);
    font-size: .6rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: .15rem .4rem;
}

/* Landmark is one cell in nineteen thousand; Wonder is one in eight hundred thousand. Landmark
   gets the outline, Wonder gets the fill, so the two are told apart by weight rather than by a
   second hue competing with the imagery. */
.cell-badge.landmark {
    color: var(--accent);
    background: transparent;
    border-color: rgba(255, 209, 102, .55);
}

.cell-badge.wonder {
    color: #06090c;
    background: var(--accent);
    border-color: transparent;
}

.cell-where,
.cell-token,
.cell-unmeasured {
    margin: 0;
    font-family: var(--mono);
    font-size: .68rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cell-unmeasured {
    font-family: var(--text);
    font-style: italic;
    opacity: .7;
}

.cell-stats {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .4rem;
    font-variant-numeric: tabular-nums;
}

.cell-stats dt {
    font-family: var(--sans);
    font-size: .58rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--muted);
}

.cell-stats dd {
    margin: 0;
    font-family: var(--mono);
    font-size: .74rem;
}

.more {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .8rem;
    text-align: center;
}

.doc-credits {
    position: static;
    padding: 0 clamp(1rem, 3vw, 2rem) 2rem;
    text-align: center;
}

@media (prefers-reduced-motion: reduce) {
    .cell-card {
        transition: none;
    }

    .cell-card:hover {
        transform: none;
    }
}

/* --- what a cell is made of --------------------------------------------------------------- */

/* A landmark cell is one of 123 in 25 million. It gets the accent and a plain statement of that,
   rather than a word like "legendary" that the collection would be asking you to take on faith. */
.landmark-note {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .45rem;
    margin: 0;
    padding: .6rem .7rem;
    font-family: var(--sans);
    font-size: .95rem;
    font-weight: 600;
    color: var(--ink);
    border: 1px solid rgba(255, 209, 102, .45);
    border-radius: 3px;
    background: rgba(255, 209, 102, .08);
}

.landmark-tag {
    font-size: .6rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #06090c;
    background: var(--accent);
    border-radius: 2px;
    padding: .15rem .4rem;
}

.landmark-rarity {
    flex-basis: 100%;
    font-family: var(--mono);
    font-size: .64rem;
    font-weight: 400;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.kv.traits {
    grid-template-columns: 1fr 1fr;
    gap: .7rem 1rem;
}

.kv.traits dd {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

.trait-note {
    margin: 0;
    font-size: .66rem;
    line-height: 1.45;
}

.inspect-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

/* An anchor styled as a button still needs to sit on the same baseline as a real one. */
.inspect-actions .btn {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
}

/* A Landmark cell is one in nineteen thousand and a Wonder is one in eight hundred thousand, so
   the two should not look alike. Landmark keeps the outlined block; Wonder fills it. */
.landmark-note.is-wonder {
    border-color: var(--accent);
    background: rgba(255, 209, 102, .16);
}

/* One line on what the place is. Wikidata's descriptions are the short kind, so this stays a
   sentence fragment rather than growing into a paragraph the panel has to scroll. */
.landmark-note-text {
    flex-basis: 100%;
    font-family: var(--text);
    font-size: .78rem;
    font-weight: 400;
    line-height: 1.45;
    color: var(--ink);
    opacity: .85;
}

.cell-note {
    margin: 0;
    font-family: var(--text);
    font-size: .72rem;
    line-height: 1.4;
    color: var(--muted);
    /* Two lines at most, so one long description cannot stretch its card out of the grid. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The map is the explanation, but it needs a sentence in front of it. Someone arriving from a link
   sees a globe covered in squares and no reason to care; this is the first thing in the panel so
   it costs no click. */
.intro {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding-bottom: .9rem;
    border-bottom: 1px solid var(--line);
}

.intro p {
    margin: 0;
    font-size: .82rem;
    line-height: 1.5;
}

.intro-more {
    color: var(--muted);
}

.intro a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 209, 102, .4);
}

.intro a:hover {
    border-bottom-color: var(--accent);
}

/* --- prose ---------------------------------------------------------------------------------
   A reading page rather than an interface. The measure is what does the work: running text set
   much wider than about 70 characters is tiring however good the type is. */

.prose {
    max-width: 760px;
    gap: 2.75rem;
}

.prose section {
    display: flex;
    flex-direction: column;
    gap: .9rem;
}

.prose h2 {
    margin: 0;
    font-family: var(--sans);
    font-size: 1.45rem;
    font-weight: 700;
    letter-spacing: .01em;
    text-wrap: balance;
}

.prose p {
    margin: 0;
    max-width: 68ch;
    font-size: .95rem;
    line-height: 1.65;
    color: rgba(230, 236, 234, .88);
}

.prose a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 209, 102, .4);
}

.prose a:hover {
    border-bottom-color: var(--accent);
}

.prose em {
    font-style: normal;
    color: var(--ink);
    border-bottom: 1px solid var(--line);
}

/* Term-and-definition pairs, for the places where the page is listing rather than arguing. */
.facts {
    margin: .2rem 0 0;
    display: flex;
    flex-direction: column;
    gap: .9rem;
    max-width: 68ch;
}

.facts>div {
    display: grid;
    grid-template-columns: 8.5rem 1fr;
    gap: .25rem 1.25rem;
    align-items: baseline;
}

.facts dt {
    font-family: var(--sans);
    font-size: .68rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--accent);
}

.facts dd {
    margin: 0;
    font-size: .92rem;
    line-height: 1.6;
    color: rgba(230, 236, 234, .88);
}

@media (max-width: 560px) {
    .facts>div {
        grid-template-columns: 1fr;
        gap: .2rem;
    }
}

/* --- scrollbars ------------------------------------------------------------------------------
   Styled rather than hidden. A hidden scrollbar on a panel that scrolls means nothing tells you
   there is more below it, and the panel does scroll once a cell is open. Thin, dim until you
   reach for it, and out of the way of the imagery behind. */

.panel,
.cell-grid,
.doc {
    scrollbar-width: thin;
    scrollbar-color: rgba(150, 175, 190, .32) transparent;
}

.panel::-webkit-scrollbar,
.doc::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.panel::-webkit-scrollbar-track,
.doc::-webkit-scrollbar-track {
    background: transparent;
}

.panel::-webkit-scrollbar-thumb,
.doc::-webkit-scrollbar-thumb {
    background: rgba(150, 175, 190, .3);
    border-radius: 99px;
    /* A transparent border with background-clip keeps the thumb clear of the panel edge without
       needing padding the content would also have to dodge. */
    border: 3px solid transparent;
    background-clip: padding-box;
}

.panel::-webkit-scrollbar-thumb:hover,
.doc::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 209, 102, .55);
    background-clip: padding-box;
}

.panel::-webkit-scrollbar-corner,
.doc::-webkit-scrollbar-corner {
    background: transparent;
}

/* Night ------------------------------------------------------------------------------------------
   The lights layer is amber and sits on exactly the ground city labels sit on, so left alone the
   two compete. Country names move off amber to a cool tone, city names give up a little weight,
   and the halo deepens because the ground behind them is darker than any daytime imagery. */
body.night .place {
    color: rgba(226, 236, 255, .88);
    text-shadow:
        0 0 3px rgba(0, 0, 0, 1),
        0 0 8px rgba(0, 0, 0, .9),
        0 1px 2px rgba(0, 0, 0, .95);
}

body.night .place.country {
    color: rgba(168, 200, 255, .78);
}

body.night .place.capital {
    color: #eaf2ff;
}

/* --- availability ------------------------------------------------------------------------------
   The panel already answers what a square is. This answers whether you can have it, which is a
   different question and deserves its own block rather than another row in the key-value list. */
.market {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    padding: .85rem 0 0;
    border-top: 1px solid var(--line);
}

.market-state {
    font-family: var(--sans);
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: .01em;
    margin: 0;
}

.market-note {
    margin: 0;
    font-size: .8rem;
    line-height: 1.45;
}

/* Figures line up under each other, so the digits should too. */
.market .kv dd {
    font-variant-numeric: tabular-nums;
}

/* Bidding. The input carries the unit inside it rather than beside it, so the field and the
   button can sit on one line in a panel this narrow. */
.bid-form {
    display: flex;
    gap: .5rem;
    align-items: stretch;
}

.bid-amount {
    position: relative;
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
}

.bid-unit {
    position: absolute;
    right: .6rem;
    font-family: var(--sans);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .1em;
    color: var(--muted);
    pointer-events: none;
}

.bid-amount input {
    width: 100%;
    min-width: 0;
    font-family: var(--mono);
    font-size: .85rem;
    color: var(--ink);
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: .5rem 2.6rem .5rem .6rem;
}

.bid-amount input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.refund {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin: 0;
}

/* --- parcels ------------------------------------------------------------------------------------
   A parcel card leads with the ground, because the shape of a run along the Hilbert curve is the
   most recognisable thing about it — far more so than its size or its id. */
.parcels-section {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.section-head {
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.section-head h2 {
    font-family: var(--sans);
    font-size: 1.3rem;
    font-weight: 600;
    margin: 0;
}

.parcel-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
}

.parcel-card {
    display: flex;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 3px;
    overflow: hidden;
    transition: border-color .15s ease, transform .15s ease;
}

.parcel-card:hover {
    border-color: var(--line-strong, rgba(150, 175, 190, .4));
    transform: translateY(-1px);
}

/* The whole card opens the map. A separate button underneath was competing with the picture for
   the same click, and the picture is the part anyone actually aims at. */
.parcel-link {
    display: flex;
    flex-direction: column;
    width: 100%;
    color: inherit;
    text-decoration: none;
}

.parcel-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.parcel-shot {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    background: #0a1220;
}

.parcel-body {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .8rem .9rem 1rem;
}

.parcel-body h3 {
    font-family: var(--sans);
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
}

.parcel-where,
.parcel-token {
    margin: 0;
    font-size: .78rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.parcel-token {
    font-family: var(--mono);
    font-size: .68rem;
    color: var(--faint, var(--muted));
    opacity: .75;
}

.parcel-has {
    margin: 0;
    font-size: .78rem;
    color: var(--accent);
}

/* The parcel a square belongs to, and the one action that changes it. */
.parcel-block {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    padding: .85rem 0 0;
    border-top: 1px solid var(--line);
}

.parcel-block .btn {
    align-self: flex-start;
}

/* --- menus --------------------------------------------------------------------------------------
   A row of buttons is fine at three and clutter at seven. These group the controls that answer one
   question each: what is drawn, and whose land to look at. Built on <details> so they open with a
   keyboard and need no script to work. */
.menu {
    position: relative;
}

.menu > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}

.menu > summary::-webkit-details-marker {
    display: none;
}

.menu > summary::after {
    content: "";
    width: 0;
    height: 0;
    border-left: 3.5px solid transparent;
    border-right: 3.5px solid transparent;
    border-top: 4px solid currentColor;
    opacity: .7;
}

.menu[open] > summary::after {
    transform: rotate(180deg);
}

.menu-body {
    position: absolute;
    top: calc(100% + .4rem);
    right: 0;
    z-index: 3;
    min-width: 12rem;
    display: flex;
    flex-direction: column;
    padding: .35rem;
    background: var(--panel);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: 4px;
    box-shadow: 0 12px 30px rgba(0, 0, 0, .45);
}

.menu-item {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .45rem .55rem;
    border: 0;
    border-radius: 2px;
    background: transparent;
    color: var(--ink);
    font-family: var(--text);
    font-size: .82rem;
    text-align: left;
    cursor: pointer;
}

.menu-item:hover,
.menu-item:focus-visible {
    background: rgba(255, 255, 255, .06);
}

.menu-item.as-button {
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
    width: 100%;
}

.menu-sub {
    font-family: var(--mono);
    font-size: .68rem;
    color: var(--muted);
}

.menu-item input[type="checkbox"] {
    accent-color: var(--accent);
    width: .9rem;
    height: .9rem;
    margin: 0;
}

/* An owner's address, in full. Truncation looks tidy and destroys the only thing the value is
   for, so it wraps instead and stays selectable. */
.market-owner {
    margin: 0;
}

.market-owner:empty {
    display: none;
}

.addr-link {
    font-family: var(--mono);
    font-size: .74rem;
    line-height: 1.5;
    color: var(--accent);
    word-break: break-all;
    text-decoration-color: rgba(255, 209, 102, .4);
    text-underline-offset: 2px;
}

.addr-link:hover {
    text-decoration-color: var(--accent);
}

/* A button carrying a glyph rather than a word. The topbar buttons are sized by their text, so
   without this the mark sits in a box the width of a label that is not there. */
.btn.icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: .55rem;
}

.btn.icon svg {
    display: block;
}

/* Contract addresses on the about page.
   The address is the point of the row, so it leads: monospace, on its own line, ahead of the
   sentence explaining what it is. An address set in the body face is unreadable as an address --
   nobody compares 40 hex characters in a proportional font. */
.contracts dd .mono {
    display: block;
    font-family: var(--mono);
    font-size: .82rem;
    letter-spacing: -.01em;
    word-break: break-all;
    margin-bottom: .35rem;
}

.contracts .kind {
    font-family: var(--mono);
    font-size: .7rem;
    font-weight: 400;
    letter-spacing: .04em;
    opacity: .6;
    margin-left: .4rem;
}
