/* Daancee: the design system from design/system, for the live site.

   The 3×3 letter grid sets the rules: square modules and rounded tiles, hairlines instead of
   boxes, heavy against light type, tracked capitals for labels, one break from the grid. The brand
   is ink and paper with one gold, the spark tile's; the four dance styles are the only other
   colour. Studio (light) and Night (dark) follow the device's own setting, which works on the
   server-rendered pages too.

   Sections: tokens · base · brand and buttons · top bar and rail · map screen · list ·
   below the map · event page · pages · footer · MudBlazor · small screens. */

/* Tokens ------------------------------------------------------------------ */

:root {
    --font-display: 'Outfit', 'Inter', system-ui, sans-serif;
    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --r-tile: 12px;
    --r-card: 16px;

    /* Studio */
    --bg: #F6F5F2;
    --bg-elev: #FAF9F7;
    --surface: #FFFFFF;
    --surface-2: #F0EEEA;
    --tile: #E8E6E2;
    --hair: #DCD9D3;
    --border: #E4E1DC;
    --border-hi: #D2CEC7;
    --text: #161616;
    --text-2: #5E5C58;
    --text-3: #9A978F;
    --sel-bg: #161616;
    --sel-fg: #FFFFFF;
    --pin-ring: #FFFFFF;
    --danger: #D93A2B;
    --shadow: 0 12px 32px rgba(30, 24, 14, 0.10);
    /* Red, gold, violet, cyan: a quarter-turn apart in hue and unequal in lightness, so a 15px pin
       or a striped cluster reads at a glance, colour-blind eyes included. A replacement colour has
       to keep that spread; two warm reds side by side is what this replaced. The admin, the
       design document and the auth emails carry copies. */
    --salsa: #E8433C;
    --bachata: #F5B000;
    --kizomba: #7A4FF0;
    --zouk: #0EA5B5;
    --salsa-soft: #FFDCD6;
    --bachata-soft: #FAE5C3;
    --kizomba-soft: #E6E3FF;
    --zouk-soft: #C2F2F9;

    /* The spark tile's gold foil (BrandPaints): its edge, body and the light band across it. Darker
       than bachata and drawn as metal, never flat, so it doesn't read as a dance. Even the light
       band holds 3:1 on paper, so the star cut through it stays readable. From monogram.js. */
    --gold-deep: #6C4812;
    --gold: #98701F;
    --gold-light: #AE8530;
}

/* Night: ink and paper swap places; nothing else changes. */
@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0E0E0F;
        --bg-elev: #121214;
        --surface: #17171A;
        --surface-2: #1D1D21;
        --tile: #26262B;
        --hair: #2A2A2F;
        --border: #232327;
        --border-hi: #313137;
        --text: #F3F2EF;
        --text-2: #A5A4A0;
        --text-3: #6E6D6A;
        --sel-bg: #F3F2EF;
        --sel-fg: #0E0E0F;
        --pin-ring: #0E0E0F;
        --danger: #FF6B5E;
        --shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
        --salsa: #FF6B5E;
        --bachata: #FFC02E;
        --kizomba: #9D7BFF;
        --zouk: #2BC6D6;
        --salsa-soft: rgba(255, 107, 94, 0.22);
        --bachata-soft: rgba(255, 192, 46, 0.22);
        --kizomba-soft: rgba(157, 123, 255, 0.24);
        --zouk-soft: rgba(43, 198, 214, 0.22);
        --gold-deep: #946822;
        --gold: #C79A3F;
        --gold-light: #E3BF68;
    }
}

/* Base -------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }
body {
    background: var(--bg);
    color: var(--text);
    font: 400 15px/1.5 var(--font-body);
    -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; margin: 0; letter-spacing: -0.03em; }
button { font: inherit; color: inherit; }

/* Tracked capitals: the label voice of the system. */
.label {
    font: 500 10.5px/1.4 var(--font-body);
    letter-spacing: .28em;
    text-transform: uppercase;
    color: var(--text-3);
}

/* Brand, tiles, tags ------------------------------------------------------ */

.brand { display: inline-flex; align-items: center; gap: 14px; text-decoration: none; color: var(--text); }
.brand .mark { width: 42px; height: 45px; display: block; }
.brand-tag { padding-left: 14px; border-left: 1px solid var(--hair); }

.icon-tile {
    width: 40px; height: 40px;
    display: inline-grid; place-items: center;
    border-radius: var(--r-tile);
    border: 1px solid var(--border-hi);
    color: var(--text-2);
    text-decoration: none;
}
.icon-tile:hover { color: var(--text); background: var(--surface-2); }

/* The language menu: a tile carrying the language's code, its list opening under it. A <details>,
   so it needs no script on the server-rendered pages. */
.lang-menu { position: relative; }
.lang-menu summary { list-style: none; cursor: pointer; font: 600 12px/1 var(--font-body); letter-spacing: .08em; }
.lang-menu summary::-webkit-details-marker { display: none; }
.lang-menu[open] summary { color: var(--text); background: var(--surface-2); }
.lang-list {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 1100;
    min-width: 168px; display: grid; padding: 6px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--shadow);
}
.lang-list a { padding: 9px 12px; border-radius: 9px; color: var(--text); text-decoration: none; font-size: 14px; }
.lang-list a:hover { background: var(--surface-2); }
.lang-list a[aria-current] { font-weight: 600; background: var(--tile); }

/* The map header's menu (SiteMenu): the account first, the languages under their label, each with
   its code, the one in use filled as in the language menu. */
.site-menu { position: relative; }
.site-menu summary { list-style: none; cursor: pointer; }
.site-menu summary::-webkit-details-marker { display: none; }
.site-menu[open] summary { color: var(--text); background: var(--surface-2); }
.site-menu-panel {
    position: absolute; right: 0; top: calc(100% + 8px); z-index: 1100;
    width: 232px; max-width: calc(100vw - 32px); display: grid; padding: 6px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--shadow);
}
.site-menu-panel a { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 9px; color: var(--text); text-decoration: none; font-size: 14px; }
.site-menu-panel a:hover { background: var(--surface-2); }
.site-menu-account { font-weight: 600; }
.site-menu-panel .label { margin-top: 6px; padding: 12px 12px 4px; border-top: 1px solid var(--hair); }
.site-menu-langs { display: grid; }
.site-menu-langs small { margin-left: auto; font: 600 11px var(--font-body); letter-spacing: .08em; color: var(--text-3); }
.site-menu-langs a[aria-current] { font-weight: 600; background: var(--tile); }

.spark-tile { display: inline-block; width: 1em; height: 1em; vertical-align: -0.12em; }
/* The light that crosses the gold is decoration: it stays still for anyone who asks. */
@media (prefers-reduced-motion: reduce) { .glint { display: none; } }

.tag {
    --c: var(--text-3);
    --soft: var(--surface-2);
    display: inline-flex; align-items: center; gap: 7px;
    height: 24px; padding: 0 9px 0 7px;
    border-radius: 7px;
    background: var(--soft);
    font-size: 12px; font-weight: 500;
    color: var(--text);
    white-space: nowrap;
    text-decoration: none;
}
.tag::before { content: ''; width: 8px; height: 8px; border-radius: 2.5px; background: var(--c); }
.tag[data-style="salsa"] { --c: var(--salsa); --soft: var(--salsa-soft); }
.tag[data-style="bachata"] { --c: var(--bachata); --soft: var(--bachata-soft); }
.tag[data-style="kizomba"] { --c: var(--kizomba); --soft: var(--kizomba-soft); }
.tag[data-style="zouk"] { --c: var(--zouk); --soft: var(--zouk-soft); }

.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); padding: 20px; }
.card h2 { font-size: 20px; margin-bottom: 14px; }
.card p { margin: 0; color: var(--text-2); }

/* Top bar and rail -------------------------------------------------------- */

.topbar {
    position: sticky; top: 0; z-index: 1000;
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
    padding: 12px 20px;
    background: color-mix(in srgb, var(--bg) 90%, transparent);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--hair);
}
.topbar-end { display: flex; justify-content: flex-end; align-items: center; gap: 8px; }

/* The map's header is one row at every width: the brand, the rail centred in what is left, and
   the buttons. Where the width runs short the tagline goes and the language menu and the account
   entry fold into one menu (SiteMenu); then the rail's tiles narrow, and on a phone it shows a
   week instead of nine days. */
.map-topbar { grid-template-columns: auto minmax(0, 1fr) auto; }
.site-menu { display: none; }

/* The rail: every day the map may ask about, a row that scrolls sideways, nine days in view - a
   week and a day either side of it. The days picked sit on one band, drawn by each picked tile's
   ::before reaching halfway into the gap on either side, so the band is plain HTML from the
   server's first paint; ink means picked, nothing else. Today is a word on a tinted tile, so it
   stands out wherever the rail is scrolled to; weekends a fainter tint, past days faded. The days come in months, the month's name over them sticking to the rail's
   start, so the first day in view always has its month written. The tiles share the rail's width
   (--show of them in view, after --peek either side: a sliver of the next day, where the rail has
   none whole to spare), up to --day each. rail.daancee.js frames the pick, and moves the fades
   and the arrows. */
.rail { position: relative; display: flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; justify-self: center; }
.rail-step {
    flex: none; width: 30px; height: 30px; margin-top: 18px; padding: 0; display: grid; place-items: center;
    border: 1px solid var(--hair); border-radius: 9px; background: transparent; color: var(--text); cursor: pointer;
}
.rail-step:hover:not(:disabled) { border-color: var(--border-hi); background: var(--surface-2); }
.rail-step:disabled { opacity: .28; cursor: default; }
.rail-step .mud-icon-root { font-size: 18px; }
.rail-days {
    --day: 52px; --gap: 4px; --pad: 9px; --show: 9; --peek: 0px;
    position: relative; flex: 0 1 auto; min-width: 0; width: calc(var(--show) * var(--day) + (var(--show) - 1) * var(--gap) + 2 * var(--pad));
    container-type: inline-size;
    display: flex; gap: var(--gap); padding: 6px var(--pad) 4px;
    overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scroll-padding-inline: calc(var(--pad) + var(--peek));
    --fade-start: 0px; --fade-end: 0px;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent);
}
.rail-days::-webkit-scrollbar { display: none; }
.rail-days.fade-start { --fade-start: 10px; }
.rail-days.fade-end { --fade-end: 10px; }
.rail-month { flex: none; display: flex; flex-direction: column; gap: 4px; }
.rail-month-days { display: flex; gap: var(--gap); }
/* Sticky within its month: it holds at the rail's start until the month's last day leaves. */
.rail-month-name {
    position: sticky; left: var(--pad); align-self: flex-start;
    font: 700 9px/12px var(--font-body); letter-spacing: .22em; text-transform: uppercase; color: var(--text-2); white-space: nowrap;
}
.rail-month.month-start .rail-month-name { left: calc(var(--pad) - 3px); margin-left: -3px; padding-left: 6px; border-left: 1px solid var(--border-hi); }
.day {
    position: relative; flex: none; scroll-snap-align: start;
    width: calc((100cqw - 2 * var(--peek) - (var(--show) - 1) * var(--gap)) / var(--show)); height: 62px; padding: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    border: 0; border-radius: 12px; background: transparent; color: var(--text);
    cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
    transition: background 140ms ease;
}
.day:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.day:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; }
.day.weekend { background: color-mix(in srgb, var(--text) 5%, transparent); }
.day.weekend:hover { background: color-mix(in srgb, var(--text) 10%, transparent); }
.day .dow { font: 600 9px/11px var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
.day .num { font: 700 21px/22px var(--font-display); letter-spacing: -0.03em; color: var(--text-2); }
.day .count { min-height: 12px; font: 600 10.5px/12px var(--font-body); color: var(--text-3); font-variant-numeric: tabular-nums; }
.day .count.unknown { width: 14px; min-height: 0; height: 6px; margin: 3px 0; border-radius: 3px; background: var(--hair); }
.day .count.counting { animation: counting 800ms ease-in-out infinite alternate; }
@keyframes counting { to { width: 20px; background: var(--border-hi); } }
.day.today { background: color-mix(in srgb, var(--text) 14%, transparent); }
.day.today:hover { background: color-mix(in srgb, var(--text) 18%, transparent); }
.day.today .dow { color: var(--text); font-weight: 700; }
.day.past > :not(.grip) { opacity: .42; }
.day.picked .num, .day.picked .count { color: var(--text); }
.day.picked .dow { color: var(--text-2); }
.day.picked.today .dow { color: var(--text); }
.day.picked::before {
    content: ''; position: absolute; z-index: -1; top: -3px; bottom: -3px; left: calc(var(--gap) / -2); right: calc(var(--gap) / -2);
    background: color-mix(in srgb, var(--text) 10%, transparent);
    border-block: 2px solid var(--text);
}
.day.picked.first::before { left: -3px; border-left: 2px solid var(--text); border-radius: 15px 0 0 15px; }
.day.picked.last::before { right: -3px; border-right: 2px solid var(--text); border-radius: 0 15px 15px 0; }
.day.picked.first.last::before { border-radius: 15px; }
/* The band's grips, shown on hover (always on a touch screen): drag one to stretch the pick. */
.day .grip {
    position: absolute; z-index: 2; top: 50%; width: 10px; height: 24px; margin-top: -12px;
    border-radius: 5px; background: var(--text); box-shadow: 0 0 0 2px var(--bg);
    cursor: ew-resize; touch-action: none; opacity: 0; transition: opacity 140ms;
}
.day .grip[data-end="first"] { left: -8px; }
.day .grip[data-end="last"] { right: -8px; }
.day .grip::before { content: ''; position: absolute; inset: -10px -8px; }
.day .grip::after { content: ''; position: absolute; left: 4px; top: 7px; bottom: 7px; width: 2px; border-radius: 1px; background: var(--bg); }
.rail:hover .grip, .rail:focus-within .grip, .rail.dragging .grip { opacity: 1; }
.rail.dragging .grip { pointer-events: none; }
/* No snapping while a drag creeps the rail on a pixel at a time: a snap would pull each pixel
   back. The tiles settle to the snap points again when the drag ends. */
.rail.dragging .rail-days { scroll-snap-type: none; }
@media (pointer: coarse) { .day .grip { opacity: 1; } }

/* Map screen -------------------------------------------------------------- */

.app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }
.explore { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 420px; }
.map-wrap { position: relative; min-height: 0; background: var(--bg); }
.map { position: absolute; inset: 0; }

.style-filter { position: absolute; top: 14px; left: 14px; right: 14px; z-index: 5; display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; pointer-events: none; }
.style-filter button {
    pointer-events: auto; flex: none;
    display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 13px 0 11px;
    border-radius: 11px; border: 1px solid var(--border-hi);
    background: color-mix(in srgb, var(--surface) 90%, transparent); color: var(--text-2);
    font-weight: 500; font-size: 13px; cursor: pointer;
    backdrop-filter: blur(10px);
}
.style-filter button i { width: 10px; height: 10px; border-radius: 3px; background: var(--c); }
.style-filter button.on { color: var(--sel-fg); border-color: var(--sel-bg); background: var(--sel-bg); }
.style-filter button.off { color: var(--text-3); }
.style-filter button.off i { background: transparent; box-shadow: inset 0 0 0 1.5px var(--c); }
/* The styles and Near me share the map's top row; the styles scroll, Near me stays at the end. */
.map-top { position: absolute; top: 14px; left: 14px; right: 14px; z-index: 5; display: flex; align-items: flex-start; gap: 6px; pointer-events: none; }
.map-top .style-filter { position: static; flex: 1; min-width: 0; }
.near-me {
    pointer-events: auto; flex: none; margin-left: auto;
    display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 13px 0 10px;
    border-radius: 11px; border: 1px solid var(--border-hi);
    background: color-mix(in srgb, var(--surface) 90%, transparent); color: var(--text);
    font-weight: 600; font-size: 13px; cursor: pointer;
    backdrop-filter: blur(10px);
}
.near-me:hover:not(:disabled) { border-color: var(--text); }
.near-me:disabled { color: var(--text-3); cursor: default; }
.near-me .mud-icon-root { font-size: 18px; }

/* Nothing on the map all week: a note where the visitor is looking, and the way to ask for the place. */
.map-empty {
    position: absolute; z-index: 4; left: 50%; bottom: 22px; transform: translateX(-50%);
    width: max-content; max-width: calc(100% - 28px);
    display: flex; align-items: center; gap: 14px; padding: 7px 7px 7px 16px;
    border-radius: 14px; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow);
    font-size: 13.5px; animation: map-empty-in 240ms ease-out;
}
.map-empty b { font-weight: 600; }
@keyframes map-empty-in { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (prefers-reduced-motion: reduce) { .map-empty { animation: none; } }
/* Nights on their way and no bubble on screen to breathe (Explorer's MapWaiting): the empty
   note's card, with a turning arc and the list's words. It holds off as the list's ghosts do, so
   a reply that comes at once never shows it. */
.map-wait {
    position: absolute; z-index: 4; left: 50%; bottom: 22px; transform: translateX(-50%);
    display: flex; align-items: center; gap: 10px; height: 38px; padding: 0 16px 0 12px; max-width: calc(100% - 28px);
    border-radius: 14px; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow);
    font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
    animation: map-empty-in 240ms ease-out 300ms both;
}
.map-wait i { flex: none; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--hair); border-top-color: var(--text); animation: map-wait-turn 900ms linear infinite; }
@keyframes map-wait-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .map-wait { animation: list-wait-in 200ms ease 300ms both; }
    .map-wait i { animation: none; border-color: var(--text-3); }
}
/* The ink button every "ask" uses: on the map, in the list, in the city search. */
.map-empty button, .ask-button, .list-ask button, .cities-none button {
    flex: none; height: 34px; padding: 0 14px; border: 0; border-radius: 10px;
    background: var(--sel-bg); color: var(--sel-fg); font: 600 13px var(--font-body); white-space: nowrap; cursor: pointer;
}
.map-empty button:hover, .ask-button:hover, .list-ask button:hover, .cities-none button:hover { opacity: .86; }

.panel { display: flex; flex-direction: column; min-height: 0; background: var(--bg-elev); border-left: 1px solid var(--hair); }
.panel-head { position: relative; padding: 18px 20px 14px; display: grid; gap: 4px; border-bottom: 1px solid var(--hair); }
/* More on its way while the list shows what it has (Explorer's Busy): a thin light runs along the
   heading's rule, and nothing listed is taken away. */
.panel.busy .panel-head::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    background: linear-gradient(90deg, transparent, var(--text-2), transparent) no-repeat;
    background-size: 40% 100%;
    animation: list-busy 1.1s ease-in-out infinite, list-wait-in 200ms ease 300ms both;
}
@keyframes list-busy { from { background-position: -70% 0; } to { background-position: 170% 0; } }
.panel-head h1 { font-size: 26px; font-weight: 800; line-height: 1.1; }
.panel-head p { margin: 0; color: var(--text-2); font-size: 13.5px; }
.list { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
/* With several days picked the list runs a day at a time under these headings. */
.list-day { flex: none; display: flex; align-items: baseline; gap: 10px; padding: 10px 4px 0; }
.list-day:first-child { padding-top: 2px; }
.list-day b { font: 700 15px var(--font-display); letter-spacing: -0.02em; }
.list-day-count { margin-left: auto; color: var(--text-3); font-size: 12px; white-space: nowrap; }
.notice { margin: 0; padding: 10px 12px; border-radius: var(--r-tile); background: var(--surface-2); color: var(--text-2); font-size: 13.5px; }

/* The bot check (turnstile.daancee.js). Laid out but invisible, so the widget can measure and run,
   until Cloudflare wants a tap: then a veil over the map and the list, which are what wait on it,
   with the card in the middle. Under 960px the page scrolls under the sticky top bar, so there the
   check is fixed to the screen below the bar (--check-top, which the script measures): wherever the
   visitor has scrolled, the card is in the middle of what they see. It sits under the top bar's
   menus and over everything on the map. */
.explore { position: relative; }
.check {
    position: absolute; inset: 0; z-index: 900;
    display: grid; place-items: center; padding: 16px;
    opacity: 0; pointer-events: none; transition: opacity 180ms ease;
}
.check.asking { opacity: 1; pointer-events: auto; }
.check-veil {
    position: absolute; inset: 0;
    background: color-mix(in srgb, var(--bg) 52%, transparent);
    -webkit-backdrop-filter: blur(3px) saturate(.6); backdrop-filter: blur(3px) saturate(.6);
}
.check-card {
    position: relative; width: min(384px, 100%); display: grid; gap: 12px; padding: 20px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--shadow);
    transform: scale(.97); transition: transform 220ms cubic-bezier(.2, .8, .2, 1);
}
.check.asking .check-card { transform: none; }
.check-card:focus { outline: none; }
.check-card h2 { margin-top: -4px; font-size: 21px; line-height: 1.15; letter-spacing: -0.02em; }
.check-wait { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 12px; align-items: center; }
.check-count { width: 44px; height: 44px; border-radius: 11px; display: grid; place-items: center; background: var(--tile); font: 700 18px/1 var(--font-display); letter-spacing: -0.03em; }
.check-wait b { display: block; font-size: 14px; font-weight: 600; line-height: 1.25; }
.check-wait small { display: block; color: var(--text-2); font-size: 12.5px; }
/* No line height: the widget's iframe is inline, and would otherwise sit on a line with a gap under it. */
.check-widget { min-height: 65px; line-height: 0; }
/* Turnstile's flexible widget is never narrower than 300px, and on a small phone the card is. There
   it is drawn at 300px and scaled down to the card's width (--fit, from the script), so it fills the
   card as it does everywhere else; Cloudflare's compact widget is a 150px square that would not. */
.check-widget.fit { min-width: 0; min-height: 0; height: calc(65px * var(--fit)); }
.check-widget.fit > * { width: 300px; transform: scale(var(--fit)); transform-origin: 0 0; }
.check-note { margin: 0; color: var(--text-3); font-size: 12px; line-height: 1.45; }
.check-failed { display: none; gap: 10px; padding: 12px; border-radius: var(--r-tile); background: var(--surface-2); color: var(--text-2); font-size: 13px; }
.check-failed b { display: block; color: var(--text); font-weight: 600; }
.check-retry {
    justify-self: start; height: 34px; padding: 0 14px; border: 0; border-radius: 10px;
    background: var(--sel-bg); color: var(--sel-fg); font-weight: 600; font-size: 13px; cursor: pointer;
}
.check.failed .check-failed { display: grid; }
.check.failed .check-widget { display: none; }

/* The day's cities (CityBudget, Explorer.razor): the quiet line under the list's heading, and the
   check's card with words and buttons in place of the widget, before the last city and once they
   are spent. The chips are the cities still open; the gold one is where the visitor is. */
.panel-left { margin: 2px 0 0; color: var(--text-3); font-size: 12.5px; }
.budget-text { margin: 0; color: var(--text-2); font-size: 13.5px; line-height: 1.45; }
.budget-row { display: flex; gap: 8px; flex-wrap: wrap; }
.budget-btn {
    height: 38px; padding: 0 16px; border: 1px solid var(--border-hi); border-radius: 11px;
    background: var(--surface); color: var(--text); font: 600 13.5px var(--font-body); cursor: pointer;
}
.budget-btn.go { background: var(--sel-bg); color: var(--sel-fg); border-color: var(--sel-bg); }
.budget-cities { display: flex; gap: 6px; flex-wrap: wrap; }
.budget-cities:empty { display: none; }
.budget-city {
    display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 11px 0 8px;
    border: 1px solid var(--border); border-radius: 9px; background: var(--surface-2); color: var(--text);
    font: 500 13px var(--font-body); cursor: pointer;
}
.budget-city:hover { border-color: var(--border-hi); }
.budget-city i { width: 8px; height: 8px; border-radius: 2.5px; background: var(--text-3); }
.budget-city.here i { background: linear-gradient(135deg, var(--gold-deep), var(--gold-light) 55%, var(--gold-deep)); }
.budget-link {
    padding: 0; border: 0; background: none; color: var(--text-2); font: inherit; cursor: pointer;
    text-decoration: underline; text-decoration-color: var(--border-hi); text-underline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) { .check-card { transform: none; transition: none; } }

/* Map popup and controls */
.maplibregl-ctrl-group { background: var(--surface) !important; border: 1px solid var(--border); border-radius: 12px !important; box-shadow: none !important; overflow: hidden; }
.maplibregl-ctrl-group button { width: 36px !important; height: 36px !important; }
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--border) !important; }
.maplibregl-ctrl-attrib { background: color-mix(in srgb, var(--bg) 75%, transparent) !important; color: var(--text-3); font-size: 10.5px; }
.maplibregl-ctrl-attrib a { color: var(--text-2) !important; }
@media (prefers-color-scheme: dark) {
    .maplibregl-ctrl-icon, .maplibregl-ctrl-attrib-button { filter: invert(1) brightness(.85); }
}
.maplibregl-popup-content { background: var(--surface) !important; color: var(--text); border-radius: 16px !important; box-shadow: var(--shadow) !important; border: 1px solid var(--border); padding: 14px 16px !important; font: 14px/1.45 var(--font-body); min-width: 230px; }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--surface) !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--surface) !important; }
.maplibregl-popup-close-button { color: var(--text-3); font-size: 18px; right: 6px !important; top: 4px !important; }
.pop .tags { display: flex; gap: 5px; flex-wrap: wrap; }
.pop h3 { font-size: 18px; margin: 8px 0 2px; }
.pop p { margin: 0 0 10px; color: var(--text-2); font-size: 13px; }
.pop-link { display: flex; align-items: center; justify-content: center; height: 36px; border-radius: 10px; background: var(--sel-bg); color: var(--sel-fg); font-weight: 600; font-size: 13px; text-decoration: none; }

/* List -------------------------------------------------------------------- */

/* Every card is one height, however long its name or however many styles: the name and the place
   end in an ellipsis, the price and the kind sit on the name's line so the styles get the card's
   whole width, and the styles keep to one row. */
.night {
    flex: none;
    display: grid; grid-template-columns: 66px minmax(0, 1fr) auto; column-gap: 14px; align-items: center;
    grid-template-areas: "tile title side" "tile where where" "tile tags tags";
    padding: 10px 14px 10px 10px; border-radius: 16px;
    background: var(--surface); border: 1px solid var(--border);
    text-decoration: none; color: inherit;
    transition: border-color 150ms ease;
}
.night:hover, .night.hl { border-color: var(--text); }
.night.past { opacity: .55; }
.night-body { display: contents; }
.night-tile { grid-area: tile; width: 66px; height: 66px; border-radius: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.night-tile b { font: 700 19px/1 var(--font-display); letter-spacing: -0.03em; }
.night-tile small { font: 500 10.5px/1.4 var(--font-body); color: var(--text-2); }
.night h3 { grid-area: title; font-size: 17px; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.night .where { grid-area: where; margin: 2px 0 7px; color: var(--text-2); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* One row of styles: a style that does not fit wraps out of sight whole rather than cut in half. */
.night .tags, .place .tags { display: flex; flex-wrap: wrap; gap: 5px; height: 24px; overflow: clip; }
.night .tags { grid-area: tags; }
.night-side { grid-area: side; display: flex; align-items: center; gap: 10px; }
.night-side .price { font-size: 13px; font-weight: 600; }
.night-side .kind { display: inline-flex; align-items: center; gap: 6px; font: 500 9.5px/1 var(--font-body); letter-spacing: .2em; text-transform: uppercase; color: var(--text-3); white-space: nowrap; }

.empty { text-align: center; padding: 40px 20px; color: var(--text-2); display: grid; gap: 12px; justify-items: center; }
.empty b { font: 700 19px var(--font-display); color: var(--text); letter-spacing: -0.02em; }

/* A country or a city counted, until the map is zoomed in on one: the night card's grammar, with
   the count in the tile and, under a country, its cities as chips. */
.place { flex: none; border-radius: 16px; background: var(--surface); border: 1px solid var(--border); transition: border-color 150ms ease; }
.place:hover, .place.hl { border-color: var(--text); }
.place-main {
    display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: 14px; align-items: center; width: 100%;
    padding: 9px 12px 9px 9px; border: 0; background: none; color: inherit; font: inherit; text-align: left;
    text-decoration: none; cursor: pointer;
}
.place-tile { width: 52px; height: 52px; border-radius: 12px; display: grid; place-items: center; font: 700 19px/1 var(--font-display); letter-spacing: -0.03em; }
.place-body { display: grid; gap: 5px; min-width: 0; }
.place-name { font: 700 17px/1.2 var(--font-display); letter-spacing: -0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.place-sub { margin-top: -4px; color: var(--text-2); font-size: 13px; }
.place-go { color: var(--text-3); }
.place:hover .place-go, .place.hl .place-go { color: var(--text); }
/* One row of cities: the ones that do not fit wrap out of sight, and the country itself is the way
   to all of them. Clipped rather than hidden, so a chip tabbed to cannot scroll the row. */
.place-cities { display: flex; flex-wrap: wrap; gap: 6px; height: 28px; overflow: clip; margin: 0 12px 12px 75px; }
.place-cities a {
    display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 9px;
    border: 1px solid var(--border); background: var(--bg-elev); color: var(--text); font: 500 13px var(--font-body);
    text-decoration: none; cursor: pointer;
}
.place-cities a:hover { border-color: var(--text); }
.place-cities small { color: var(--text-3); font-size: 12px; }
/* Nothing to list yet (Explorer's Waiting): quiet cards the shape of what is coming, under a line
   that says what. They fade in after a moment, so an answer that comes at once never flashes them. */
.list-wait { flex: none; display: flex; flex-direction: column; gap: 8px; animation: list-wait-in 200ms ease 300ms both; }
.list-wait-label { margin: 2px 4px 0; color: var(--text-3); font-size: 12.5px; }
.ghost {
    display: grid; grid-template-columns: 66px minmax(0, 1fr); gap: 14px; align-items: center;
    padding: 10px; border-radius: 16px; background: var(--surface); border: 1px solid var(--border);
}
.ghost-tile { width: 66px; height: 66px; border-radius: 12px; background: var(--tile); }
.ghost-lines { display: grid; gap: 8px; }
.ghost-lines i { width: 58%; height: 15px; border-radius: 7px; background: var(--tile); }
.ghost-lines i:nth-child(2) { width: 82%; height: 11px; }
.ghost-lines i:nth-child(3) { width: 44%; height: 22px; }
.ghost-place { grid-template-columns: 52px minmax(0, 1fr); padding: 9px; }
.ghost-place .ghost-tile { width: 52px; height: 52px; }
.ghost-place .ghost-lines i:nth-child(2) { display: none; }
.ghost-tile, .ghost-lines i { animation: dz-wait 1.4s ease-in-out infinite; }
.ghost:nth-child(3) :is(.ghost-tile, i) { animation-delay: .15s; }
.ghost:nth-child(4) :is(.ghost-tile, i) { animation-delay: .3s; }
.ghost:nth-child(5) :is(.ghost-tile, i) { animation-delay: .45s; }
@keyframes list-wait-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .list-wait, .ghost-tile, .ghost-lines i { animation: none; }
    .panel.busy .panel-head::after { animation: list-wait-in 200ms ease 300ms both; background-size: 100% 100%; opacity: .5; }
}
.list-hint { flex: none; margin: 4px 0 0; padding: 6px 4px; text-align: center; color: var(--text-3); font-size: 12.5px; }
/* The list's last word, whatever it shows: a dashed card, the place a missing city would go. */
.list-ask { flex: none; margin-top: 6px; display: grid; gap: 4px; justify-items: start; padding: 16px; border-radius: 16px; border: 1px dashed var(--border-hi); }
.list-ask b { font: 700 15.5px var(--font-display); letter-spacing: -0.02em; }
.list-ask span { color: var(--text-2); font-size: 13px; line-height: 1.45; }
.list-ask button { margin-top: 8px; }
.empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.empty-actions .ask-button { height: 36.5px; padding: 0 16px; border-radius: var(--r-tile); }

/* Below the map: the week's words, cities ---------------------------------- */

.below, .page { max-width: 1120px; margin: 0 auto; padding: 56px 20px 24px; display: grid; gap: 56px; }
.section-head { display: grid; gap: 6px; margin-bottom: 20px; }
.section-head h2 { font-size: 32px; font-weight: 800; letter-spacing: -0.04em; line-height: 1.05; }

/* The words of a city's week (CityWords): names only, A to Z, the nights largest, then venues,
   then areas. Nothing here says when or where; the line above points up to the map. */
.words { display: grid; gap: 18px; }
.words .section-head p { margin: 0; color: var(--text-2); font-size: 14.5px; }
.words .section-head p a { color: var(--text); }
.words-cloud {
    list-style: none; margin: 0; padding: 20px 0; display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 10px 22px; border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
}
.word-night { font: 700 21px var(--font-display); letter-spacing: -0.02em; }
.word-night a { text-decoration: none; }
.word-night a:hover { text-decoration: underline; }
.word-venue { color: var(--text-2); font-size: 15.5px; font-weight: 500; }
.word-area { color: var(--text-3); font-size: 13.5px; }
.style-links { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

/* The city index (CityGrid): one question and a field, then the countries A to Z, five to a line.
   Type and hairlines, no boxes but the field and an open country; 70 countries stay a screen or
   two tall. */
.cities a { color: inherit; text-decoration: none; }
.cities mark { background: none; color: var(--text); box-shadow: inset 0 -1px 0 var(--text); }
.cities-ask { position: relative; display: grid; justify-items: center; gap: 8px; text-align: center; padding-bottom: 32px; }
.cities-ask h2 { font-size: 34px; font-weight: 800; letter-spacing: -0.045em; line-height: 1.05; text-wrap: balance; }
.cities-ask > p { margin: 0; color: var(--text-2); font-size: 14px; font-variant-numeric: tabular-nums; }
.cities-search { position: relative; width: min(600px, 100%); margin-top: 10px; text-align: left; }
.cities-field {
    display: flex; align-items: center; gap: 12px; height: 50px; padding: 0 18px;
    border-radius: 14px; border: 1px solid var(--border-hi); background: var(--surface); color: var(--text-3);
    transition: border-color .15s; cursor: text;
}
.cities-field:focus-within { border-color: var(--text); }
.cities-field input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; color: var(--text); font: 400 16px var(--font-body); }
.cities-field input::placeholder { color: var(--text-3); }
.cities-field input::-webkit-search-cancel-button { display: none; }
.cities-field kbd { padding: 2px 7px; border: 1px solid var(--border-hi); border-radius: 6px; font: 500 11px var(--font-body); }
.cities-found {
    position: absolute; z-index: 5; left: 0; right: 0; top: calc(100% + 8px); margin: 0; padding: 6px; list-style: none;
    border-radius: 16px; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow);
}
.cities-found a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1px 14px; padding: 9px 14px; border-radius: 11px; }
.cities-found a:hover, .cities-found [aria-selected="true"] a { background: var(--surface-2); }
.cities-found b { font: 600 15.5px var(--font-display); letter-spacing: -0.01em; }
.cities-found small { grid-column: 1; color: var(--text-3); font-size: 12px; }
.cities-found span { grid-row: 1 / 3; grid-column: 2; align-self: center; color: var(--text-2); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.cities-none { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; padding: 8px 8px 8px 14px; color: var(--text-2); }
.cities-missing { margin: 2px 0 0; color: var(--text-3); font-size: 13px; }
.cities-missing button { padding: 0; border: 0; background: none; color: var(--text); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.cities-near { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px; margin: 4px 0 0; color: var(--text-3); font-size: 13px; }
.cities-near span { margin-right: 2px; }
.cities-near a { padding: 4px 11px; border-radius: 999px; border: 1px solid var(--border); color: var(--text); font-weight: 500; }
.cities-near a:hover { border-color: var(--text); }
.cities-near small { margin-left: 5px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.cities-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px 20px; padding-bottom: 8px; border-bottom: 1px solid var(--text); }
.cities-head h3 { font-size: 17px; letter-spacing: -0.025em; }
.cities-jump { display: flex; flex-wrap: wrap; gap: 2px; }
.cities-jump a { min-width: 24px; height: 24px; display: grid; place-items: center; border-radius: 6px; color: var(--text-2); font: 600 11.5px var(--font-body); }
.cities-jump a:hover { background: var(--surface-2); color: var(--text); }
.cities-letter { display: grid; grid-template-columns: 36px minmax(0, 1fr); padding: 7px 0; border-bottom: 1px solid var(--hair); scroll-margin-top: 16px; }
.cities-l { padding-top: 5px; font: 700 15px/1 var(--font-display); color: var(--text-3); }
.cities-countries { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0 20px; }
.cities-country {
    display: flex; align-items: baseline; justify-content: flex-start; gap: 6px; min-width: 0; padding: 3px 0; border: 0; background: none;
    text-align: left; color: var(--text); font: 500 13.5px var(--font-body); white-space: nowrap; cursor: pointer;
}
.cities-country span { overflow: hidden; text-overflow: ellipsis; }
.cities-country small { color: var(--text-3); font-size: 11px; font-variant-numeric: tabular-nums; }
.cities-country:hover span, .cities-country[aria-expanded="true"] span { text-decoration: underline; text-underline-offset: 4px; }
.cities-panel { grid-column: 2; margin: 8px 0 6px; padding: 14px 18px; border-radius: var(--r-card); border: 1px solid var(--border); background: var(--surface); }
.cities-panel-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 8px; }
.cities-panel-head b { font: 700 17px var(--font-display); letter-spacing: -0.025em; }
.cities-panel-head span { color: var(--text-3); font-size: 12.5px; }
.cities-close { margin-left: auto; padding: 0 2px; border: 0; background: none; color: var(--text-3); font-size: 20px; line-height: 1; cursor: pointer; }
.cities-close:hover { color: var(--text); }
.cities-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0 24px; }
.cities-list a { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; border-top: 1px solid var(--hair); font-size: 14.5px; }
.cities-list a:hover b { text-decoration: underline; text-underline-offset: 3px; }
.cities-list b { font-weight: 600; }
.cities-list span { color: var(--text-3); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.cities-shade { position: fixed; inset: 0; z-index: 90; background: rgba(0, 0, 0, .35); }
@keyframes cities-up { from { transform: translateY(30px); opacity: 0; } }
/* A phone opens a country as a sheet from the bottom, over the page. */
.cities-panel.sheet {
    position: fixed; z-index: 91; left: 0; right: 0; bottom: 0; max-height: 72vh; overflow-y: auto; margin: 0;
    padding: 10px 20px calc(24px + env(safe-area-inset-bottom)); border: 0; border-top: 1px solid var(--border-hi);
    border-radius: 24px 24px 0 0; box-shadow: 0 -20px 50px rgba(0, 0, 0, .35); animation: cities-up .22s ease-out;
}
.cities-panel.sheet::before { content: ""; display: block; width: 38px; height: 4px; margin: 0 auto 14px; border-radius: 2px; background: var(--border-hi); }
.cities-panel.sheet .cities-list { grid-template-columns: 1fr; }
@media (prefers-reduced-motion: reduce) { .cities-panel.sheet { animation: none; } }

/* Ask for your city (CityAsk, ask.daancee.js): the bot check's card in the middle, over the same
   veil, as a native dialog so Escape, focus and the page behind it behave on their own. */
.ask { width: min(460px, calc(100% - 24px)); max-width: none; max-height: none; margin: auto; padding: 0; border: 0; background: none; color: var(--text); overflow: visible; }
.ask::backdrop { background: rgba(20, 18, 14, .32); -webkit-backdrop-filter: blur(3px) saturate(.6); backdrop-filter: blur(3px) saturate(.6); }
.ask-card {
    position: relative; display: grid; gap: 12px; padding: 22px; max-height: calc(100dvh - 24px); overflow-y: auto;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--shadow);
}
.ask-card[hidden] { display: none; }
.ask[open] .ask-card { animation: ask-in 220ms cubic-bezier(.2, .8, .2, 1); }
@keyframes ask-in { from { opacity: 0; transform: scale(.97); } }
@media (prefers-reduced-motion: reduce) { .ask[open] .ask-card { animation: none; } }
.ask-card h2 { margin-top: -4px; padding-right: 30px; font-size: 22px; line-height: 1.15; letter-spacing: -0.02em; }
.ask-intro { margin: -4px 0 2px; color: var(--text-2); font-size: 13.5px; line-height: 1.5; }
.ask-close {
    position: absolute; top: 12px; right: 12px; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 9px;
    background: none; color: var(--text-3); font-size: 22px; line-height: 1; cursor: pointer;
}
.ask-close:hover { background: var(--surface-2); color: var(--text); }
.ask-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ask-field { display: grid; gap: 6px; min-width: 0; }
.ask-field > span { font-size: 12.5px; font-weight: 600; }
.ask-field small { color: var(--text-3); font-weight: 400; }
.ask-field input, .ask-field textarea {
    width: 100%; min-width: 0; padding: 11px 13px; border-radius: var(--r-tile); border: 1px solid var(--border-hi);
    background: var(--bg-elev); color: var(--text); font: 400 15px/1.4 var(--font-body); outline: 0; transition: border-color .15s;
}
.ask-field textarea { min-height: 100px; resize: vertical; }
.ask-field input:focus, .ask-field textarea:focus { border-color: var(--text); }
.ask-field input::placeholder, .ask-field textarea::placeholder { color: var(--text-3); }
/* Empty unless Cloudflare wants a tap; then the widget, scaled down in a form narrower than it. */
.ask-widget { line-height: 0; }
.ask-widget:empty { display: none; }
.ask-widget.fit { overflow: hidden; }
.ask-widget.fit > * { width: 300px; transform: scale(var(--fit)); transform-origin: 0 0; }
.ask-error { margin: 0; padding: 10px 12px; border-radius: var(--r-tile); background: var(--surface-2); color: var(--danger); font-size: 13px; }
.ask-error[hidden] { display: none; }
.ask-actions { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.ask-actions small { flex: 1; color: var(--text-3); font-size: 11.5px; line-height: 1.4; }
.ask-cancel, .ask-send { flex: none; height: 40px; padding: 0 16px; border-radius: 11px; font-weight: 600; font-size: 13.5px; cursor: pointer; }
.ask-cancel { border: 1px solid var(--border-hi); background: none; color: var(--text); }
.ask-cancel:hover { background: var(--surface-2); }
.ask-send { border: 0; background: var(--sel-bg); color: var(--sel-fg); }
.ask-send:disabled { opacity: .6; cursor: default; }
.ask-sending, .sending .ask-send > span:first-child { display: none; }
.sending .ask-sending { display: inline; }
.ask-done { justify-items: center; text-align: center; padding: 30px 22px 22px; }
.ask-done h2 { padding-right: 0; }
.ask-tick { width: 48px; height: 48px; border-radius: 13px; display: grid; place-items: center; background: var(--sel-bg); color: var(--sel-fg); }

/* Event page -------------------------------------------------------------- */

/* The venue's map is the cover, and the night sits on it as a place card, the way a maps app shows
   a place: what a dancer needs to decide on the card (when, where, the three actions), what they
   need to plan in rows beside it, each fact once.
   The map is a link: it, and Directions, open the phone's own maps app (night.daancee.js). */
.event-page { padding-bottom: 40px; }
.event-cover { position: relative; height: 330px; }
/* --pin-x and --pin-y are where the venue sits on the map, clear of the card: map.daancee.js pads
   the map until the pin lands there. */
.event-cover .venue-map { position: absolute; inset: 0; display: block; overflow: hidden; background: var(--tile); --pin-x: 68%; --pin-y: 40%; }
.venue-pin { width: 18px; height: 18px; border-radius: 6px; box-shadow: 0 0 0 3px var(--pin-ring), 0 3px 10px rgba(0, 0, 0, .32); }
.venue-open, .event-back {
    position: absolute; z-index: 3; top: 16px; height: 34px;
    display: inline-flex; align-items: center; gap: 7px; border-radius: 999px;
    border: 1px solid var(--border-hi); background: color-mix(in srgb, var(--surface) 88%, transparent);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    color: var(--text); font: 600 12.5px var(--font-body); text-decoration: none; white-space: nowrap;
}
.venue-open { right: 20px; padding: 0 13px 0 11px; }
.event-back { left: 20px; padding: 0 13px 0 10px; }
.venue-open .mud-icon-root, .event-back .mud-icon-root { font-size: 16px; }
.venue-map:hover .venue-open, .event-back:hover { background: var(--surface); }

/* The card rises over the map's lower edge and the rows start under the map, beside it. Where the
   body overlaps the map it lets clicks through, so all of the map stays a link. */
.event-body {
    position: relative; z-index: 4; max-width: 1120px; margin: -128px auto 0; padding: 0 20px;
    display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr);
    grid-template-areas: "card side" "main side"; grid-template-rows: auto 1fr;
    gap: 32px 48px; align-items: start; pointer-events: none;
}
.event-body > * { pointer-events: auto; }
.event-card {
    grid-area: card; position: relative; display: grid; gap: 8px; padding: 22px 24px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 22px; box-shadow: var(--shadow);
}
.event-card h1 { margin-top: 2px; font-size: 34px; line-height: 1.04; font-weight: 800; letter-spacing: -0.04em; }
/* A night written in other languages than the page's shows each further title under the first,
   quieter, so a visitor reads whichever they know without choosing. */
.event-card .also-title { margin: -2px 0 0; font: 600 19px/1.15 var(--font-display); letter-spacing: -0.02em; color: var(--text-2); }
.event-when { margin: 0; font: 600 16.5px/1.3 var(--font-display); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.event-when i { margin: 0 7px; font-style: normal; color: var(--text-3); }
.event-where { margin: 0; color: var(--text-2); font-size: 14px; }
.event-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
/* The cached page's card until the details come (EventPage, night.daancee.js): three quiet bars
   where when, where and the actions will be, and the bot check over the page when it wants a tap. */
.event-page { position: relative; }
.event-waiting { display: grid; gap: 9px; margin-top: 6px; }
.event-waiting span { height: 14px; border-radius: 7px; background: var(--tile); }
.event-waiting span:nth-child(1) { width: 62%; height: 18px; }
.event-waiting span:nth-child(2) { width: 44%; }
.event-waiting span:nth-child(3) { width: 78%; height: 36px; border-radius: 999px; margin-top: 8px; }
.event-page.waiting .event-waiting span { animation: dz-wait 1.4s ease-in-out infinite; }
@keyframes dz-wait { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .event-page.waiting .event-waiting span { animation: none; } }
.event-problem { margin: 4px 0 0; color: var(--text-2); font-size: 14px; }
.event-page:not(.waiting) .event-waiting { display: none; }

.event-side { grid-area: side; display: grid; gap: 26px; padding-top: 150px; }
.event-rows { display: grid; border-top: 1px solid var(--hair); }
.event-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 11px 0; border-bottom: 1px solid var(--hair); }
.event-row-icon { width: 36px; height: 36px; border-radius: 11px; display: grid; place-items: center; background: var(--tile); color: var(--text-2); }
.event-row-icon .mud-icon-root { font-size: 18px; }
.event-row .label { display: block; font-size: 9px; }
.event-row b { display: block; font-size: 14.5px; font-weight: 600; }
.event-row-more { display: block; color: var(--text-2); font-size: 13px; }
.event-row .also { display: block; color: var(--text-3); font-size: 12.5px; }
/* Who each price is for, after the range ("Students ₺200"), never broken in two. */
.event-row .tier { white-space: nowrap; }
/* What we don't know is quiet, and says where to ask. */
.event-row.quiet b { font-weight: 500; color: var(--text-2); }
.event-row-more a { color: var(--text); font-weight: 600; text-decoration: underline; text-decoration-color: var(--border-hi); text-underline-offset: 3px; }
.event-row-more a:hover { text-decoration-color: currentColor; }
/* Copy address needs the clipboard, so night.daancee.js shows it; a tick says it worked. */
.copy-address {
    width: 36px; height: 36px; padding: 0; display: grid; place-items: center;
    border: 1px solid var(--border-hi); border-radius: 10px; background: transparent; color: var(--text-2); cursor: pointer;
}
.copy-address[hidden] { display: none; }
.copy-address:hover { color: var(--text); background: var(--surface-2); }
.copy-address .mud-icon-root { font-size: 17px; }
.copy-address .mud-icon-root:last-child, .copy-address.copied .mud-icon-root:first-child { display: none; }
.copy-address.copied .mud-icon-root:last-child { display: block; }

.event-host { display: grid; gap: 2px; }
.event-host > b { font: 700 17px/1.25 var(--font-display); letter-spacing: -0.02em; }
/* Under the host: where the details come from, and the way to report one wrong. */
.event-check-note { margin: 0; padding-top: 14px; border-top: 1px solid var(--hair); color: var(--text-3); font-size: 12.5px; line-height: 1.5; }
.event-check-note span { display: block; margin-top: 6px; }
.event-check-note a { color: var(--text-2); text-underline-offset: 3px; }
.event-check-note a:hover { color: var(--text); }
.socials { display: grid; margin-top: 8px; }
.social { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 0; border-top: 1px solid var(--hair); text-decoration: none; }
.social-icon { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--tile); color: var(--text); }
.social-text { min-width: 0; display: grid; }
.social-text b { font-weight: 600; font-size: 14px; }
.social-text span { color: var(--text-3); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.social-out { color: var(--text-3); }
.social:hover b { text-decoration: underline; }

.event-main { grid-area: main; display: grid; gap: 30px; padding: 0 4px; }
.event-section h2 { margin-bottom: 10px; font: 500 10.5px/1.4 var(--font-body); letter-spacing: .28em; text-transform: uppercase; color: var(--text-3); }
.event-section p { margin: 0; max-width: 640px; color: var(--text-2); font-size: 15px; line-height: 1.65; }
.about-languages { display: grid; gap: 16px; }
.about-languages > div { display: grid; gap: 6px; }
.about-languages > div + div { padding-top: 16px; border-top: 1px solid var(--hair); }
.timeline { display: grid; }
.slot { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; padding: 10px 0; border-top: 1px solid var(--hair); }
.slot:first-child { border-top: 0; padding-top: 2px; }
.slot b { font: 700 15px var(--font-display); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.slot > span { color: var(--text-2); }
.slot .also { display: block; color: var(--text-3); font-size: 12.5px; }
.dates { display: flex; flex-wrap: wrap; gap: 6px; }
.date { width: 56px; height: 64px; border-radius: 12px; border: 1px solid var(--hair); display: flex; flex-direction: column; align-items: center; justify-content: center; text-decoration: none; }
.date small { font: 500 8.5px/1.3 var(--font-body); letter-spacing: .2em; text-transform: uppercase; color: var(--text-3); }
.date b { font: 700 18px/1.1 var(--font-display); letter-spacing: -0.03em; }
.date.weekend { background: var(--tile); border-color: var(--tile); }
.date:hover { border-color: var(--text); }
.note { margin: 0; color: var(--text-3); font-size: 12.5px; }

/* Narrower, the card spans the page and the rows follow it. */
@media (max-width: 960px) {
    .event-cover .venue-map { --pin-x: 50%; }
    .event-body { margin-top: -96px; grid-template-columns: minmax(0, 1fr); grid-template-areas: "card" "side" "main"; grid-template-rows: none; gap: 28px; }
    .event-side { padding-top: 0; }
}

/* On a phone the card is a sheet drawn up over the map, its three actions side by side under the
   thumb, as in a maps app. */
@media (max-width: 600px) {
    .event-cover { height: 236px; }
    .event-back { top: 14px; left: 14px; width: 36px; height: 36px; padding: 0; justify-content: center; }
    .event-back span { display: none; }
    .venue-open { top: 14px; right: 14px; height: 36px; }
    .event-body { margin-top: -26px; padding: 0; gap: 0; }
    .event-card {
        gap: 6px; padding: 20px 16px 18px; background: var(--bg);
        border-width: 1px 0 0; border-radius: 22px 22px 0 0; box-shadow: 0 -12px 30px rgba(0, 0, 0, .2);
    }
    .event-card::after { content: ''; position: absolute; top: 7px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--border-hi); }
    .event-card h1 { font-size: 26px; }
    .event-when { font-size: 15px; }
    .event-actions { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); margin-top: 12px; }
    .event-actions .mud-button-root { height: 58px; padding: 0 6px; }
    .event-actions .mud-button-label { display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 12px; }
    .event-actions .mud-button-icon-start { margin: 0; }
    .event-side { padding: 0 16px; gap: 22px; }
    .event-main { padding: 28px 16px 0; gap: 26px; }
}

/* Other pages ------------------------------------------------------------- */

.page h1 { font-size: 48px; font-weight: 800; letter-spacing: -0.045em; line-height: 1; margin: 8px 0 14px; }
.page > p, .account > p { color: var(--text-2); font-size: 16px; max-width: 560px; margin: 0; }
.account, .not-found { display: grid; gap: 0; justify-items: start; }
.not-found .mud-button-root { margin-top: 24px; }
.account-points { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 32px; border-top: 1px solid var(--hair); border-left: 1px solid var(--hair); width: 100%; }
.account-points > div { display: grid; gap: 6px; padding: 20px; border-right: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }
.account-points b { font: 700 19px var(--font-display); letter-spacing: -0.02em; }
.account-points span { color: var(--text-2); font-size: 14px; }
.account-next { margin-top: 40px; }
.account-next + .account-points { margin-top: 12px; }

/* The sign-in island: a narrow tile; its fields and buttons are MudBlazor's. */
.account-panel { display: grid; gap: 14px; width: 100%; max-width: 420px; margin-top: 28px; padding: 22px; border: 1px solid var(--hair); border-radius: var(--r-card); background: var(--surface); }
.account-panel form { display: grid; gap: 12px; }
.account-panel .who { font: 700 22px var(--font-display); letter-spacing: -0.02em; overflow-wrap: anywhere; }
.account-panel .hint { color: var(--text-2); font-size: 14px; margin: 0; }
.account-modes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.account-modes button {
    height: 38px; border-radius: 11px; border: 1px solid var(--border-hi);
    background: var(--surface); color: var(--text-2); font-weight: 500; font-size: 14px; cursor: pointer;
}
.account-modes button.on { color: var(--sel-fg); border-color: var(--sel-bg); background: var(--sel-bg); }
.account-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.account-panel .account-forgot { justify-self: start; }
.account-panel .account-agree { font-size: 13px; }
.account-agree a { color: var(--text); }

/* Terms and privacy (LegalArticle): the account page's voice for a long read. The switch is the
   account panel's two modes as links; the summary is the account page's ruled cells, numbered;
   the parts read at a measure, with their contents held beside them on a wide screen. */
.legal { gap: 40px; }
.legal-head { display: grid; justify-items: start; }
.legal-head > p { color: var(--text-2); font-size: 16px; max-width: 620px; margin: 0; }
.legal-switch { display: inline-grid; grid-auto-flow: column; gap: 6px; margin-bottom: 26px; }
.legal-switch a {
    display: flex; align-items: center; height: 36px; padding: 0 16px; border-radius: 11px; border: 1px solid var(--border-hi);
    background: var(--surface); color: var(--text-2); font-weight: 500; font-size: 14px; text-decoration: none;
}
.legal-switch a:hover { color: var(--text); }
.legal-switch a[aria-current] { color: var(--sel-fg); border-color: var(--sel-bg); background: var(--sel-bg); }
.legal-updated { margin-top: 16px; color: var(--text-3); font-size: 13px; }
.legal-short { display: grid; gap: 12px; }
.legal-short ol {
    list-style: none; counter-reset: short; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; padding: 0;
    border-top: 1px solid var(--hair); border-left: 1px solid var(--hair);
}
.legal-short li {
    counter-increment: short; display: grid; grid-template-columns: 30px minmax(0, 1fr); padding: 18px 20px;
    border-right: 1px solid var(--hair); border-bottom: 1px solid var(--hair); font-size: 15px; line-height: 1.55;
}
.legal-short li::before { content: counter(short); font: 700 19px/1.2 var(--font-display); color: var(--gold); }
.legal-short a, .legal-parts a { color: var(--text); text-decoration-color: var(--gold); text-underline-offset: 3px; }
.legal-body { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 56px; align-items: start; }
.legal-toc { position: sticky; top: 24px; display: grid; gap: 2px; }
.legal-toc .label { margin-bottom: 8px; }
.legal-toc a { display: grid; grid-template-columns: 26px minmax(0, 1fr); padding: 5px 0; color: var(--text-2); font-size: 13.5px; line-height: 1.35; text-decoration: none; }
.legal-toc a:hover { color: var(--text); }
.legal-toc i, .legal-part h2 i { font-style: normal; color: var(--text-3); font-variant-numeric: tabular-nums; }
.legal-parts { display: grid; gap: 36px; max-width: 700px; }
.legal-part { scroll-margin-top: 24px; padding-top: 22px; border-top: 1px solid var(--hair); }
.legal-part h2 { display: grid; grid-template-columns: 34px minmax(0, 1fr); font-size: 22px; letter-spacing: -0.025em; margin-bottom: 12px; }
.legal-part p, .legal-part ul { margin: 0 0 12px 34px; color: var(--text-2); font-size: 15px; line-height: 1.65; }
.legal-part ul { padding-left: 18px; }
.legal-part li + li { margin-top: 6px; }
.legal-part li::marker { color: var(--gold); }

/* Footer ------------------------------------------------------------------ */

/* Two rows under one heavy rule. More pages wrap on their line; more languages only lengthen the
   menu, which opens upwards, eight to a column. */
.site-footer { max-width: 1120px; margin: 40px auto 0; padding: 0 20px 32px; }
.footer-top { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; padding: 22px 0 18px; border-top: 1px solid var(--text); }
.footer-brand { display: flex; align-items: center; gap: 14px; margin-right: auto; color: var(--text); text-decoration: none; }
.footer-brand .mark { width: 32px; height: 35px; display: block; flex: none; }
.footer-brand b { display: block; font: 700 15px/1.3 var(--font-display); letter-spacing: -0.015em; }
.footer-brand small { display: block; color: var(--text-3); font-size: 12px; }
.footer-links { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.footer-links a { color: var(--text-2); text-decoration: none; font-size: 13.5px; }
.footer-links a:hover { color: var(--text); }
.footer-lang { position: relative; }
.footer-lang summary {
    list-style: none; display: flex; align-items: center; gap: 7px; height: 30px; padding: 0 11px;
    border: 1px solid var(--border); border-radius: 999px; color: var(--text-2); font: 600 12.5px var(--font-body); cursor: pointer;
}
.footer-lang summary::-webkit-details-marker { display: none; }
.footer-lang summary:hover, .footer-lang[open] summary { color: var(--text); border-color: var(--border-hi); }
.footer-chev { transition: transform .2s; }
.footer-lang:not([open]) .footer-chev { transform: rotate(180deg); }
.footer-langs {
    position: absolute; z-index: 20; right: 0; bottom: calc(100% + 8px); display: grid; grid-auto-flow: column; grid-template-rows: repeat(8, auto);
    padding: 6px; border-radius: 14px; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow);
}
.footer-langs a { padding: 6px 12px; border-radius: 9px; color: var(--text-2); text-decoration: none; font-size: 13.5px; white-space: nowrap; }
.footer-langs a:hover { background: var(--surface-2); color: var(--text); }
.footer-langs a[aria-current] { color: var(--text); font-weight: 600; }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding-top: 14px; border-top: 1px solid var(--hair); color: var(--text-3); font-size: 12px; }
.footer-legal { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.footer-legal a { color: var(--text-3); text-decoration: none; }
.footer-legal a:hover { color: var(--text); }

/* MudBlazor: buttons as squircles and the Night ground ------------------- */

.mud-button-root { border-radius: var(--r-tile) !important; }
.mud-button-outlined { border-color: var(--border-hi) !important; color: var(--text) !important; }
.mud-button-outlined:hover { background: var(--surface-2) !important; }
@media (prefers-color-scheme: dark) {
    /* html:root outranks the :root block MudThemeProvider writes, wherever it lands in the page. */
    html:root {
        --mud-palette-primary: #F3F2EF;
        --mud-palette-primary-text: #0E0E0F;
        --mud-palette-primary-darken: #FFFFFF;
        --mud-palette-primary-lighten: #FFFFFF;
        --mud-palette-background: #0E0E0F;
        --mud-palette-surface: #17171A;
        --mud-palette-text-primary: #F3F2EF;
        --mud-palette-text-secondary: #A5A4A0;
        --mud-palette-action-default: #A5A4A0;
        --mud-palette-lines-default: #232327;
        --mud-palette-lines-inputs: #313137;
        --mud-palette-divider: #2A2A2F;
    }
}

/* Small screens ----------------------------------------------------------- */

/* The map's header, short of room for the rail at its widest: the tagline goes, and the language
   menu and the account entry fold into the menu. */
@media (max-width: 1000px) {
    .map-topbar .brand-tag, .map-topbar .lang-menu, .map-topbar .account-button { display: none; }
    .map-topbar .site-menu { display: block; }
}

@media (max-width: 960px) {
    .page-topbar { grid-template-columns: 1fr auto; grid-template-areas: "brand end"; }
    .page-topbar .brand { grid-area: brand; }
    .page-topbar .topbar-end { grid-area: end; }
    .app { height: auto; display: block; }
    .explore { display: block; }
    .map-wrap { height: 56vh; }
    .panel { border-left: 0; }
    .list { overflow: visible; }
    .check { position: fixed; top: var(--check-top, 0px); padding: 12px; }
    .account-points { grid-template-columns: 1fr; }
    /* The contents would stand alone above a long read: the parts' own numbers are enough. */
    .legal-body { grid-template-columns: minmax(0, 1fr); }
    .legal-toc { display: none; }
}

@media (max-width: 600px) {
    .topbar { padding: 10px 16px; }
    .brand .mark { width: 38px; height: 41px; }
    .brand-tag { display: none; }
    /* On a phone the header keeps its one row by giving the rail what the mark and the menu leave:
       a week of tiles rather than nine days, with a sliver of the day either side so the rail
       reads as a strip that goes on, and a margin either side so a tap or a grip at the rail's
       ends lands on a day and not on the mark or the menu. The rail is compact: the tiles are
       shorter and their words smaller, and the header's padding is tighter, so the map gets the
       height. A phone swipes the rail, so its arrows go. */
    .map-topbar { gap: 8px; padding: 6px 16px; }
    .map-topbar .brand .mark { width: 32px; height: 35px; }
    .map-topbar .icon-tile { width: 36px; height: 36px; }
    .rail { width: calc(100% - 20px); max-width: 376px; }
    .rail-step { display: none; }
    .rail-days { --gap: 2px; --pad: 4px; --show: 7; --peek: 10px; flex: 1; width: auto; padding: 4px var(--pad) 3px; }
    .rail-month { gap: 2px; }
    .rail-month-name { font-size: 8px; line-height: 10px; letter-spacing: .16em; }
    .day { height: 46px; gap: 0; border-radius: 9px; }
    .day .dow { font-size: 7.5px; line-height: 9px; letter-spacing: .04em; }
    /* The word for today is the longest label (Сегодня) and the tile is narrow: no tracking. */
    .day.today .dow { letter-spacing: 0; }
    .day .num { font-size: 16px; line-height: 17px; }
    .day .count { min-height: 10px; font-size: 9.5px; line-height: 10px; }
    .day .count.unknown { margin: 2px 0; }
    .day .grip { height: 20px; margin-top: -10px; }
    .day .grip::after { top: 5px; bottom: 5px; }
    .near-me-label, .back-label { display: none; }
    .near-me { width: 36px; padding: 0; justify-content: center; }
    /* Clear of the zoom buttons in the bottom-right corner. */
    .map-empty { left: 12px; right: 58px; bottom: 12px; width: auto; max-width: none; transform: none; flex-wrap: wrap; gap: 8px 12px; animation: none; }
    .ask-card { padding: 18px; }
    .ask-row { grid-template-columns: 1fr; }
    .ask-actions { flex-wrap: wrap; }
    .ask-actions small { flex-basis: 100%; order: 1; }
    .ask-cancel { margin-left: auto; }
    .panel-head { padding: 16px 16px 12px; }
    .night { grid-template-columns: 60px minmax(0, 1fr) auto; column-gap: 12px; }
    .night-tile { width: 60px; height: 60px; }
    .ghost { grid-template-columns: 60px minmax(0, 1fr); gap: 12px; }
    .ghost-tile { width: 60px; height: 60px; }
    .ghost-place { grid-template-columns: 52px minmax(0, 1fr); }
    .ghost-place .ghost-tile { width: 52px; height: 52px; }
    .place-cities { margin-left: 9px; }
    .check-card { padding: 16px; }
    .below, .page { padding-left: 16px; padding-right: 16px; }
    .legal h1 { font-size: 38px; }
    .legal-short ol { grid-template-columns: minmax(0, 1fr); }
    .legal-short li { padding: 16px; }
    .legal-part h2 { grid-template-columns: 28px minmax(0, 1fr); font-size: 20px; }
    .legal-part p, .legal-part ul { margin-left: 0; }
    .cities-ask { padding-bottom: 24px; }
    .cities-ask h2 { font-size: 26px; }
    .cities-field { height: 46px; padding: 0 14px; }
    .cities-field kbd, .cities-jump { display: none; }
    .cities-letter { grid-template-columns: 24px minmax(0, 1fr); padding: 6px 0; }
    .cities-l { font-size: 13px; }
    .cities-countries { grid-template-columns: 1fr 1fr; gap: 0 14px; }
    .cities-country { font-size: 13px; }
    .words-cloud { gap: 8px 16px; }
    .word-night { font-size: 18px; }
    .page h1 { font-size: 36px; }
    .footer-brand { flex-basis: 100%; }
    .footer-links { flex-basis: 100%; gap: 8px 18px; }
    .footer-langs { left: 0; right: auto; }
    .footer-bottom { flex-direction: column; }
}
