/* Self-hosted, no request to Google: space-grotesk-var.woff2 is a variable font (weight axis), so
   one file covers 400/500/700; the browser interpolates the exact weight from it. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Silkscreen';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/silkscreen-700.woff2') format('woff2');
}
:root {
  --accent: #d83c2c;
  --accent-dark: #bd3023;
  --gold: #e0b23c;
  --ink: #182031;
  --muted: #626c7b;
  --line: rgba(30, 33, 40, 0.10);
  --panel: rgba(255, 255, 255, 0.96);
  --shadow-sm: 0 2px 8px rgba(20, 24, 40, 0.08);
  --shadow: 0 8px 28px rgba(20, 24, 40, 0.14);
  --shadow-lg: 0 24px 72px rgba(16, 20, 34, 0.26);
  --r: 14px;
  --font: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --top: 76px;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; font-family: var(--font); color: var(--ink); background: #cfe3ef; -webkit-font-smoothing: antialiased; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: transparent; }
a { color: inherit; }
h1, h2, h3 { margin: 0; line-height: 1.12; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
[hidden] { display: none !important; }

#city { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }


/* ---------- chrome ---------- */
.topbar { position: fixed; inset: 0 0 auto 0; height: var(--top); display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 0 22px; background: #fff; box-shadow: 0 1px 0 var(--line), 0 6px 24px rgba(0,0,0,0.06); z-index: 30; }
.brand { display: flex; align-items: baseline; gap: 0; font-family: 'Silkscreen', 'Press Start 2P', monospace; font-weight: 700; font-size: 24px; letter-spacing: 0.02em; text-decoration: none; white-space: nowrap; line-height: 1; }
.brand .w { color: var(--accent); }
.brand .h { color: var(--ink); }
.brand span:not(.w):not(.h) { color: var(--muted); font-family: var(--font); font-size: 14px; font-weight: 500; margin-left: 10px; }
.topbar nav { display: flex; align-items: center; gap: 6px; }
.topbar nav button:not(.btn), .topbar nav a:not(.btn) { padding: 10px 14px; border-radius: 10px; font-weight: 500; text-decoration: none; }
.topbar nav button:not(.btn):hover, .topbar nav a:not(.btn):hover { background: #f2f3f6; }

.btn { border-radius: 11px; padding: 11px 18px; font-weight: 700; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: background 0.15s, transform 0.08s; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-dark); }
.btn-ghost { background: #f0f1f4; color: var(--ink); }
.btn-ghost:hover { background: #e5e7ec; }
.btn-pay { background: #ffc439; color: #16214d; font-size: 17px; padding: 14px 18px; }
.btn-pay:hover { background: #f5b920; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.block { width: 100%; }
.link-btn { color: var(--accent); font-weight: 700; font-size: 12px; text-decoration: underline; padding: 0; margin-top: 4px; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.hero { position: fixed; top: calc(var(--top) + 22px); left: 26px; max-width: 540px; z-index: 12; pointer-events: none; }
.hero h1 { font-size: 46px; font-weight: 700; text-shadow: 0 2px 0 #fff, 0 0 10px #fff, 0 0 26px rgba(255,255,255,0.95), 0 0 46px rgba(255,255,255,0.8); }
.hero p { margin: 10px 0 16px; font-size: 19px; text-shadow: 0 1px 0 #fff, 0 0 8px #fff, 0 0 18px rgba(255,255,255,0.95); }
.pill { display: inline-flex; align-items: center; gap: 8px; background: var(--panel); border-radius: 999px; padding: 10px 18px; box-shadow: var(--shadow); font-weight: 500; pointer-events: auto; }
.pill b { font-weight: 700; }
.dot { width: 9px; height: 9px; border-radius: 50%; background: #3fae4f; box-shadow: 0 0 0 4px rgba(63,174,79,0.18); }

.panel { position: fixed; background: var(--panel); border-radius: var(--r); box-shadow: var(--shadow); z-index: 12; }
.eyebrow { font-size: 11.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: #b07d1c; display: flex; align-items: center; gap: 6px; }
.eyebrow.success { color: #2f8f45; }
.pin { width: 12px; height: 12px; border-radius: 50% 50% 50% 0; background: var(--accent); transform: rotate(-45deg); }
.muted { color: var(--muted); }
.tiny { font-size: 12.5px; }
.center { text-align: center; }

.district-panel { top: calc(var(--top) + 22px); right: 26px; width: 292px; padding: 18px 20px 20px; }
.district-panel .headline { font-size: 26px; font-weight: 700; margin: 8px 0 10px; }
.ringbar { height: 8px; border-radius: 999px; background: #eceef2; overflow: hidden; margin-bottom: 6px; }
.ringbar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), #f28c28); border-radius: 999px; transition: width 0.6s; }
.district-panel .tiny { margin: 0 0 10px; }

/* Grows upward from the bottom, so on a short window it used to climb straight through the headline.
   The cap keeps the top of the screen free: that is where a first-time visitor reads what this is. */
.ticker { left: 26px; bottom: 26px; width: 356px; padding: 14px 14px; scrollbar-gutter: stable; max-height: calc(100vh - var(--top) - 247px); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
/* The leaderboard: the number everyone is playing for, always in the corner of the eye. */
/* ---------- the value board ----------
   Rank, mark, company and what the building is worth. The company name is allowed to wrap: this
   list exists to show WHO is up there, and a name cut off after eighteen characters does not do
   that (Max, 17.9.2026: "auch so das die komplett zu sehen sind"). The domain under the name is
   what people recognise, and the value on the right is the only figure in brand red, so the eye
   lands on it first. */
.valuelist { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 5px; }
.valuelist li { display: flex; align-items: center; gap: 10px; cursor: pointer; border-radius: 11px;
  padding: 9px 8px; margin: 0; border: 1px solid transparent; }
.valuelist li:hover { background: #fdf4f3; border-color: #f3d8d4; }
.valuelist li .no { flex: none; width: 24px; height: 24px; border-radius: 7px; background: #eceff4; color: var(--muted);
  font-style: normal; font-size: 11.5px; font-weight: 800; display: grid; place-items: center; font-variant-numeric: tabular-nums; }
.valuelist li:nth-child(-n+3) .no { background: var(--accent); color: #fff; }
.valuelist li .mark { flex: none; width: 40px; height: 40px; border-radius: 10px; }
.valuelist li .mark.initials { font-size: 13.5px; }
.valuelist .who { min-width: 0; display: grid; gap: 1px; white-space: normal; }
.valuelist .who em, .valuelist .worth em { margin-left: 0; }
/* Nothing in this list may ever be wide enough to need sideways scrolling. */
.valuelist li { max-width: 100%; }
.valuelist .who b { font-size: 15px; font-weight: 700; line-height: 1.22; overflow-wrap: anywhere; }
.valuelist .who em { font-style: normal; font-size: 12px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.valuelist .worth { margin-left: auto; flex: none; text-align: right; display: grid; gap: 1px; }
.valuelist .worth b { font-size: 18px; font-weight: 800; color: var(--accent); letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; }
.valuelist .worth em { font-style: normal; font-size: 9.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.eyebrow .crown { color: var(--gold, #e0b23c); font-size: 10px; }
/* The board heading is a <button>, so it has to be stripped back to looking like text. The chevron
   only appears where the board actually folds, which is the phone. */
.board-toggle { width: 100%; background: none; border: 0; padding: 0; margin: 0; font: inherit;
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: #b07d1c; text-align: left; cursor: default; }
.board-toggle .chev { display: none; }

/* The brand mark: a company's logo everywhere the company is named. White tile, soft corner, the
   logo contained inside it with a little breathing room, so every logo looks deliberate whatever
   its shape. Missing logos fall back to initials on the brand colour, never to an empty box. */
.mark { flex: none; width: 24px; height: 24px; border-radius: 7px; background: #fff; border: 1px solid var(--line);
        display: inline-grid; place-items: center; overflow: hidden; vertical-align: middle; }
.mark img { width: 100%; height: 100%; object-fit: contain; padding: 2px; box-sizing: border-box; }
.mark.initials { color: #fff; font-size: 9.5px; font-weight: 700; letter-spacing: .02em; border: none; }
.mark.sm { width: 20px; height: 20px; border-radius: 6px; margin-right: 6px; }
.mark.sm.initials { font-size: 8.5px; }
.ticker ul li .mark { margin: 0; }
.standing .rival-link { display: inline-flex; align-items: center; text-decoration: none; color: inherit; border-radius: 8px; padding: 2px 4px; margin: -2px -4px; }
.standing .rival-link:hover { background: #fff; }
.standing .rival-link b { margin-right: 4px; }
.duel-row .mark.sm { margin: 0 2px; }

/* Standing: where this building sits in the city, and who is next above it. */
.standing { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 12px 0 4px;
            padding: 11px 14px; border-radius: 12px; background: #f4f6fa; border: 1.5px solid var(--line); font-size: 13.5px; }
.standing .rank { font-size: 21px; font-weight: 700; line-height: 1; }
.standing .rank small { font-size: 12.5px; font-weight: 500; color: var(--muted); }
.standing .chase { color: var(--muted); }
.standing .chase b { color: #1e2128; }
.standing.crowned { background: #fff8e6; border-color: var(--gold, #e0b23c); }
.standing.crowned .rank { color: #b07d1c; }

/* Active duels shown on a building's card. */
.duel-list { display: grid; gap: 7px; margin: 4px 0 14px; }
.duel-row { display: flex; align-items: center; gap: 9px; padding: 9px 12px; border-radius: 11px;
            border: 1.5px solid var(--line); background: #fff; font-size: 13.5px; text-decoration: none; color: inherit; }
.duel-row:hover { border-color: var(--accent); }
.duel-row .vs { font-weight: 700; color: var(--muted); font-size: 11.5px; letter-spacing: .06em; flex: none; }
.duel-row .rival { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.duel-row .score { margin-left: auto; flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
.duel-row .score.up { color: #2f8f45; } .duel-row .score.down { color: #b3352b; } .duel-row .score.level { color: var(--muted); }
.ticker .feed-head { margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--line); }
.ticker ul { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 7px; font-size: 13px; }
.ticker ul li { display: flex; align-items: center; gap: 8px; cursor: pointer; border-radius: 6px; }
.ticker ul li:hover { color: var(--accent); }
.ticker ul li i { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.ticker ul li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticker ul li em { font-style: normal; color: var(--muted); margin-left: auto; flex: none; font-size: 12px; }

.district-bar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 26px; display: flex; gap: 4px; padding: 6px; background: var(--panel); border-radius: 999px; box-shadow: var(--shadow); z-index: 12; max-width: min(720px, calc(100vw - 52px)); overflow-x: auto; scrollbar-width: none; }
.district-bar::-webkit-scrollbar { display: none; }
.district-bar button { display: flex; align-items: center; gap: 7px; padding: 9px 15px; border-radius: 999px; font-weight: 500; white-space: nowrap; font-size: 13.5px; }
.district-bar button:hover { background: #f0f1f4; }
.district-bar button.active { background: var(--ink); color: #fff; }
.district-bar i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.district-bar em { font-style: normal; color: var(--muted); font-size: 12px; }
.district-bar button.active em { color: rgba(255,255,255,0.7); }

.viewport-tools { position: fixed; right: 26px; bottom: 26px; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; z-index: 12; }
.viewport-tools .sep { grid-column: 1 / -1; }
.viewport-tools button { width: 44px; height: 44px; border-radius: 12px; background: var(--panel); box-shadow: var(--shadow-sm); font-size: 20px; font-weight: 700; color: var(--ink); display: grid; place-items: center; }
.viewport-tools button:hover { background: #fff; box-shadow: var(--shadow); }

.hint-bar { position: fixed; right: 130px; bottom: 32px; font-size: 12.5px; color: #4b515e; background: var(--panel); padding: 8px 14px; border-radius: 999px; box-shadow: var(--shadow-sm); z-index: 11; }

.legal { position: fixed; left: 26px; bottom: 6px; font-size: 11.5px; color: #4b515e; z-index: 11; }
.legal a { text-decoration: none; }
.legal a:hover { text-decoration: underline; }
/* The legal links have to stay reachable on a phone too (§ 5 DDG: the imprint must be available
   from every page). Kept small, bottom-left, above the Safari toolbar like the street-view button. */
@media (max-width: 760px) {
  .legal { left: 12px; right: 12px; bottom: calc(8px + env(safe-area-inset-bottom)); font-size: 10.5px;
    text-align: center; padding: 5px 8px; border-radius: 9px; background: #ffffffd9;
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: var(--shadow-sm); }
}
@media (max-width: 1280px) { .hint-bar { display: none; } }
.tooltip { position: fixed; z-index: 20; background: var(--panel); border-radius: 12px; box-shadow: var(--shadow); padding: 11px 14px; pointer-events: none; max-width: 270px; font-size: 13px; transform: translate(14px, 14px); }
.tooltip[hidden] { display: none; }
.tooltip b { font-size: 15px; display: block; margin-bottom: 2px; }
.tooltip .tt-cta { display: inline-block; margin-top: 8px; background: var(--accent); color: #fff; font-weight: 700; padding: 6px 11px; border-radius: 8px; font-size: 12.5px; }
.tooltip .price { color: var(--accent); font-weight: 700; }
.tooltip .tt-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.tooltip img { width: 38px; height: 38px; border-radius: 9px; object-fit: contain; background: #fff; box-shadow: inset 0 0 0 1px var(--line); }

.toast { position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%); background: var(--ink); color: #fff; padding: 12px 20px; border-radius: 11px; z-index: 70; box-shadow: var(--shadow); font-weight: 500; max-width: min(420px, 90vw); text-align: center; }
.toast[hidden] { display: none; }

/* ---------- modals ---------- */
.modal { position: fixed; inset: 0; background: rgba(18, 22, 34, 0.5); display: grid; place-items: center; z-index: 50; padding: 16px; backdrop-filter: blur(3px); }
.modal[hidden] { display: none; }
.sheet { position: relative; background: #fff; border-radius: 20px; width: min(470px, 100%); max-height: calc(100vh - 32px); overflow-y: auto; overflow-x: hidden; padding: 28px 28px 24px; box-shadow: var(--shadow-lg); }
.sheet h2 { font-size: 27px; margin: 5px 0 12px; }
.close { position: absolute; top: 13px; right: 13px; width: 36px; height: 36px; border-radius: 50%; font-size: 24px; line-height: 1; color: var(--muted); z-index: 2; }
.close:hover { background: #f2f3f6; color: var(--ink); }

.plot-prices { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 14px 0 18px; }
.plot-prices div { border: 1.5px solid var(--line); border-radius: 12px; padding: 10px 8px; text-align: center; }
.plot-prices .thumb { height: 52px; }
.plot-prices .thumb svg { width: 100%; height: 100%; }
.plot-prices b { display: block; font-size: 13px; margin-top: 4px; }
.plot-prices span { color: var(--accent); font-weight: 700; }
/* Keeps clear of the close button in the corner: a longer company name used to run underneath it.
   min-width:0 is what actually lets the text column shrink (a flex item refuses to go below its
   longest word by default), and the wrap rule breaks a name that has nowhere to break. */
.resident-head { display: flex; gap: 15px; align-items: center; padding-right: 40px; }
.resident-head > div { min-width: 0; }
/* break-word, not anywhere: "anywhere" also shrinks the column to its smallest possible width, so
   ordinary names started breaking mid-word even with room to spare. This breaks only when a word
   genuinely does not fit. */
.resident-head h2 { overflow-wrap: break-word; }
.avatar { width: 66px; height: 66px; border-radius: 15px; display: grid; place-items: center; font-weight: 700; font-size: 24px; color: #fff; flex: none; overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.badges { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.badge { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: #f0f1f4; color: #4b515e; }
.badge.gold { background: #fdf1cd; color: #8a5c00; }
.slogan { font-size: 17px; margin: 16px 0 12px; }
.facts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 0 0 18px; }
.facts dt { font-size: 12px; color: var(--muted); }
.facts dd { margin: 2px 0 0; font-weight: 500; }
.row { display: flex; align-items: center; }
.row.gap { gap: 8px; }
.row > .btn { flex: 1; }
.row input { flex: 1; min-width: 0; }

/* ---------- wizard ---------- */
.wizard { width: min(960px, 100%); padding: 24px 26px 0; display: flex; flex-direction: column; }
.wizard .wizard-body { flex: 1; }
.wizard-foot { position: sticky; bottom: 0; background: #fff; border-top: 1.5px solid var(--line); margin: 18px -26px 0; padding: 12px 26px; display: flex; align-items: center; justify-content: space-between; gap: 12px; z-index: 2; }
.wizard-foot .row .btn { min-width: 130px; }
.wizard-foot .btn-primary { padding: 12px 26px; font-size: 15.5px; }
.wizard-foot .btn-pay { padding: 12px 22px; font-size: 15px; }
.wizard-foot .row .btn-pay { min-width: 0; }
.wizard-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding-right: 40px; }
.wizard-head h2 { font-size: 25px; margin-top: 4px; }
.reservation { display: flex; align-items: center; gap: 7px; background: #fff6e5; color: #8a5c00; border-radius: 999px; padding: 8px 15px; font-size: 13.5px; font-weight: 500; white-space: nowrap; }
.reservation.urgent { background: #fde8e6; color: #b3352b; }
.reservation b { font-variant-numeric: tabular-nums; }

.steps { list-style: none; display: flex; gap: 6px; margin: 18px 0 18px; padding: 0; }
.steps li { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; color: var(--muted); padding: 8px 12px; border-radius: 999px; background: #f5f6f8; flex: 1; min-width: 0; }
.steps li span { width: 21px; height: 21px; border-radius: 50%; background: #dfe1e6; color: #6b7180; display: grid; place-items: center; font-size: 12px; font-weight: 700; flex: none; }
.steps li.active { background: var(--ink); color: #fff; }
.steps li.active span { background: var(--accent); color: #fff; }
.steps li.done span { background: #3fae4f; color: #fff; }

.wizard-body { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; align-items: start; }
.wizard-body > * { min-width: 0; }
.wizard-main h3 { font-size: 20px; margin-bottom: 4px; }
.wizard-main > .step > p { margin: 0 0 16px; }

.type-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.type-card { min-width: 0; }
.type-card { border: 2px solid var(--line); border-radius: 15px; padding: 14px 12px; text-align: left; background: #fff; transition: border-color 0.15s, box-shadow 0.15s; }
.type-card:hover { border-color: #c8ccd4; }
.type-card.active { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(224,69,59,0.12); }
.type-card .thumb { height: 78px; border-radius: 10px; margin-bottom: 10px; background: linear-gradient(180deg, #dff0fb, #eef6fb); display: grid; place-items: end center; overflow: hidden; }
.type-card .thumb svg { width: 100%; height: 100%; }
.type-card b { display: block; font-size: 15px; }
.type-card small { color: var(--muted); display: block; line-height: 1.35; margin: 3px 0 8px; }
.type-card .price { font-weight: 700; font-size: 19px; }
.type-card.current { border-color: #3fae4f; }
.type-card .tagpill { font-size: 10.5px; font-weight: 700; color: #2f8f45; text-transform: uppercase; letter-spacing: 0.06em; }
.type-card { position: relative; }
.type-card .flag { position: absolute; top: -9px; left: 12px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; background: var(--ink); color: #fff; }
.type-card .flag.hot { background: var(--accent); }
.type-card .flag.gold { background: var(--gold); color: #3a2a00; }
.type-card ul { list-style: none; padding: 0; margin: 6px 0 8px; font-size: 12px; color: #454b58; display: grid; gap: 3px; }
.type-card ul li::before { content: '✓ '; color: #2f8f45; font-weight: 700; }
.type-card .price small { font-size: 12px; color: var(--muted); font-weight: 500; }
/* Height is the product, so every card states it before anything else. */
.type-card .floors-badge { display: inline-flex; align-items: baseline; gap: 4px; margin: 5px 0 2px; padding: 3px 9px;
                           border-radius: 999px; background: #eef1f7; color: #454b58; font-size: 12px; font-weight: 500; }
.type-card .floors-badge b { display: inline; font-size: 14.5px; font-weight: 700; color: var(--ink); }
.type-card .floors-badge em { font-style: normal; color: var(--muted); font-size: 11px; }
.type-card.active .floors-badge { background: #fdeceb; }
.type-card .floors-badge.gold { background: #fdf3d8; color: #6b5410; }
.type-card .floors-badge.gold b { color: #8a6a12; }
.type-card .calc.saving { color: #6b5410; background: #fdf3d8; border-radius: 8px; padding: 6px 9px; margin-top: 6px; }
.type-card .calc.saving b { display: inline; font-size: inherit; }
.type-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.unsell { margin-top: 12px; }
.req { font-size: 10.5px; font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: 0.06em; margin-left: 4px; }
.dropzone.over { border-color: var(--accent); background: #fff4f2; }
.bump { border: 2px dashed var(--gold); border-radius: 14px; padding: 12px 14px; margin: 14px 0 4px; background: #fffbef; display: flex; gap: 12px; align-items: flex-start; }
.bump input { width: 18px; height: 18px; margin-top: 3px; accent-color: var(--accent); flex: none; }
.bump b { display: block; }
.bump small { color: #6b5a2a; display: block; margin-top: 2px; }
.bump .bump-price { margin-left: auto; font-weight: 700; white-space: nowrap; color: var(--accent); }
.trust { list-style: none; padding: 0; margin: 14px 0 6px; display: grid; gap: 6px; font-size: 13px; color: #454b58; }
.trust li::before { content: '✓'; color: #2f8f45; font-weight: 700; margin-right: 8px; }

form label, .label { display: block; font-size: 13px; font-weight: 700; margin: 14px 0 5px; }
form input[type=text], form input[type=url], form input[type=email], form input[type=password], input[readonly], textarea, form input:not([type]) {
  width: 100%; padding: 11px 13px; border: 1.5px solid #d7dae1; border-radius: 11px; font-weight: 500; background: #fff;
}
input:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(224,69,59,0.14); }
textarea { resize: vertical; }
.upload-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; margin-top: 16px; }
.upload > div { min-width: 0; }
.upload { display: flex; gap: 11px; align-items: flex-start; border: 1.5px dashed #d7dae1; border-radius: 13px; padding: 12px; }
.upload.filled { border-style: solid; border-color: #3fae4f; }
.upload b { font-size: 13.5px; display: block; }
.upload small { display: block; color: var(--muted); font-size: 11.5px; line-height: 1.35; margin-bottom: 6px; }
.upload input[type=file] { font-size: 11.5px; width: 100%; max-width: 100%; display: block; }
.upload-preview { width: 54px; height: 54px; border-radius: 10px; background: #f2f3f6; display: grid; place-items: center; font-size: 10.5px; color: var(--muted); flex: none; overflow: hidden; font-weight: 700; }
.upload-preview img { width: 100%; height: 100%; object-fit: contain; }

.color-group { margin-bottom: 16px; }
.color-group header { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.color-group h4 { margin: 0; font-size: 14px; }
.color-group .surcharge { font-size: 12px; font-weight: 700; color: #2f8f45; background: #e8f6ea; padding: 2px 9px; border-radius: 999px; }
.color-group.premium .surcharge { color: #8a5c00; background: #fdf1cd; }
.swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.swatch { width: 40px; height: 40px; border-radius: 11px; border: 3px solid transparent; position: relative; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.10); }
.swatch.active { border-color: var(--ink); }
.swatch.active::after { content: '✓'; position: absolute; inset: 0; display: grid; place-items: center; color: #fff; font-size: 16px; font-weight: 700; text-shadow: 0 1px 3px rgba(0,0,0,0.55); }
.swatch[data-material=metal] { background-image: linear-gradient(135deg, rgba(255,255,255,0.75), rgba(255,255,255,0) 45%, rgba(0,0,0,0.18)); }
.swatch[data-material=neon] { box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1), 0 0 12px currentColor; }
.swatch[data-material=holo], .swatch[data-material=pearl] { background-image: linear-gradient(120deg, #ff8ad8, #8ab8ff, #8affd0, #fff08a); }

.summary { border: 1.5px solid var(--line); border-radius: 14px; padding: 14px 16px; }
.summary.compact { padding: 12px 14px; margin-top: 14px; font-size: 13.5px; }
.summary .line { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; }
.summary .line span:first-child { color: #454b58; }
.summary .total { display: flex; justify-content: space-between; border-top: 1.5px solid var(--line); margin-top: 8px; padding-top: 10px; font-weight: 700; font-size: 19px; }
.summary .meta { font-size: 12.5px; color: var(--muted); margin-bottom: 8px; }
.check { display: grid; grid-template-columns: 17px 1fr; gap: 10px; align-items: start; font-size: 13px; margin: 16px 0 12px; line-height: 1.5; cursor: pointer; }
.check a { color: var(--accent); }
.check input { margin-top: 2px; flex: none; width: 17px; height: 17px; accent-color: var(--accent); }
/* The order bump (Aufgabe 8, 18.9.2026): dashed on purpose, so it reads as a separable add-on
   rather than part of the price the buyer already agreed to on the cards above. Sits 12px above
   the legal line, which itself sits right above the pay button. */
.check.bump { grid-template-columns: 20px 1fr; background: #fff6e5; border: 1px dashed var(--gold, #e0b23c);
  border-radius: 12px; padding: 12px 14px; margin: 0 0 12px; }
.check.bump input { width: 20px; height: 20px; margin-top: 1px; }
.check.bump b { font-weight: 700; }
.check.bump .amount { font-family: 'Silkscreen', 'Press Start 2P', monospace; color: var(--accent); font-weight: 700; }
.error { color: #b3352b; font-weight: 500; background: #fdeceb; padding: 10px 13px; border-radius: 10px; font-size: 13.5px; }

.wizard-side { position: sticky; top: 0; }
.preview-wrap { background: linear-gradient(180deg, #cfe8fb 0%, #e8f2f8 62%, #dfeadb 100%); border-radius: 15px; overflow: hidden; aspect-ratio: 1 / 1; }
.preview-wrap canvas, #wz-preview { width: 100%; height: 100%; display: block; }
.preview-caption { margin: 10px 2px 0; display: flex; flex-direction: column; gap: 1px; font-size: 13.5px; }
.wizard-nav { margin-top: 14px; }

.share-image { width: 100%; border-radius: 12px; display: block; margin-bottom: 8px; box-shadow: var(--shadow-sm); }
.owner-box { background: #f6f7f9; border-radius: 13px; padding: 14px 16px; margin: 16px 0; }
.owner-box input { margin-top: 8px; font-size: 12px; }
.howto { padding-left: 20px; display: grid; gap: 9px; line-height: 1.45; }
code { background: #f2f3f6; padding: 2px 6px; border-radius: 5px; font-size: 12px; }

@media (max-width: 900px) {
  .wizard-body { grid-template-columns: minmax(0, 1fr); }
  .wizard-side { position: static; display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 12px; align-items: start; }
  .preview-wrap { grid-row: span 2; }
  .wizard-nav { grid-column: 2; }
  .preview-caption { grid-column: 2; }
}
.narrow-only { display: none; }
@media (max-width: 760px) {
  :root { --top: 58px; }
  .topbar { padding: 0 14px; }
  .topbar .btn { white-space: nowrap; }
  .brand { font-size: 18px; }
  .topbar nav button:not(.btn), .topbar nav a:not(.btn) { display: none; }
  .btn { padding: 10px 14px; font-size: 14px; }
  .hero { left: 14px; right: 14px; top: calc(var(--top) + 14px); }
  .hero h1 { font-size: 30px; }
  .hero p { font-size: 15px; margin: 6px 0 12px; }
  .ticker, .hint-bar { display: none; }
  .district-panel { top: auto; bottom: 132px; left: 14px; right: 14px; width: auto; padding: 13px 15px; }
  .district-panel .headline { font-size: 20px; margin: 4px 0 10px; }
  .district-bar { bottom: 14px; left: 14px; right: 14px; transform: none; max-width: none; }
  .viewport-tools { right: 14px; top: calc(var(--top) + 150px); bottom: auto; grid-template-columns: 1fr; }
  .viewport-tools button { width: 40px; height: 40px; }
  .viewport-tools .sep, .viewport-tools [data-action=whole-city], .viewport-tools [data-action=climb-up], .viewport-tools [data-action=climb-down] { display: none; }
  .sheet { padding: 22px 18px 18px; border-radius: 18px; width: 100%; }
  .sheet h2 { font-size: 22px; }
  .wizard { padding: 20px 16px 16px; }
  .wizard-head { flex-direction: column; gap: 8px; padding-right: 44px; }
  .wizard-head h2 { font-size: 21px; }
  .reservation { align-self: flex-start; padding: 6px 12px; font-size: 12.5px; }
  .wizard-side { grid-template-columns: 1fr; }
  .wizard-nav { grid-column: 1; }
  .preview-caption { grid-column: 1; }
  .type-grid { grid-template-columns: 1fr; }
  .wizard-foot { margin: 14px -16px 0; padding: 10px 16px; }
  .wizard-foot .row .btn { min-width: 0; }
  .type-card { display: grid; grid-template-columns: 92px 1fr; gap: 12px; align-items: center; }
  .type-card .thumb { height: 66px; margin: 0; }
  .upload-row { grid-template-columns: 1fr; }
  .steps li { padding: 7px 9px; font-size: 0; gap: 0; justify-content: center; }
  .steps li.active { font-size: 13px; gap: 8px; flex: 2; }
  .facts { grid-template-columns: 1fr; }
}
/* Narrow phones. Must come after the 760px block so these values win. "Build my building" wrapping
   into two lines inside its own button is the first thing that looks unfinished on a small screen,
   so the label shortens and the header keeps to one line. */
@media (max-width: 430px) {
  .wide-only { display: none; }
  .narrow-only { display: inline; }
  .topbar { padding: 0 11px; gap: 8px; }
  .topbar .btn { padding: 9px 12px; font-size: 13.5px; }
  .brand { font-size: 16px; }
  .hero h1 { font-size: 27px; }
  .hero p { font-size: 14.5px; }
  /* More city, less panel: the map is the product, and on a small screen the boxes were eating it. */
  .district-panel { bottom: 116px; padding: 12px 14px; }
  .district-panel .headline { font-size: 18px; margin: 3px 0 8px; }
  .district-bar { bottom: 12px; }
  .district-bar button { padding: 7px 11px; font-size: 12.5px; gap: 5px; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Checkout as a drawer on wide screens: the city stays visible and the building appears on its plot. */
.nudge { display: grid; gap: 8px; background: #fff6e5; border: 1.5px solid #f2c96b; border-radius: 14px; padding: 14px 16px; margin: 14px 0 18px; }
.nudge b { font-size: 15px; }
.nudge span { color: #6b5a2a; font-size: 13.5px; }
.nudge .btn { justify-self: start; }
@media (min-width: 1100px) {
  #modal-checkout { justify-items: end; align-items: stretch; padding: 12px; background: rgba(18, 22, 34, 0.18); backdrop-filter: none; }
  #modal-checkout .wizard { width: 600px; max-height: calc(100vh - 24px); border-radius: 18px; }
  #modal-checkout .wizard-body { grid-template-columns: minmax(0, 1fr); }
  #modal-checkout .wizard-side .preview-wrap, #modal-checkout .wizard-side .preview-caption { display: none; }
  #modal-checkout .type-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Elevator in the building card */
.elevator { margin: 10px 0 4px; padding: 10px 12px; border: 1px solid var(--line, #e6e2da); border-radius: 12px; background: #faf8f4; }
.elevator-head { display: flex; justify-content: space-between; font-size: 12px; color: #6b665e; margin-bottom: 6px; }
.elevator-head b { color: #1c1a17; }
.elevator input[type=range] { width: 100%; accent-color: #e0453b; }
.elevator-btns { display: flex; gap: 6px; margin-top: 8px; }
.elevator-btns .chip { flex: 1; font-size: 12px; padding: 5px 0; border-radius: 999px; border: 1px solid #e6e2da; background: #fff; cursor: pointer; }
.elevator-btns .chip:hover { border-color: #e0453b; color: #e0453b; }
.viewport-tools .sep { display: block; height: 1px; background: #e6e2da; margin: 2px 6px; }

/* Own colour (hex) picker */
.color-group.custom .surcharge { color: #5b2a86; background: #efe6fa; }
.custom-colour { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px; border: 1px dashed #d8d3ca; border-radius: 12px; background: #fbfaf7; width: 100%; margin-top: 8px; }
.custom-colour.active { border-style: solid; border-color: var(--ink); }
.custom-colour input[type=color] { width: 44px; height: 40px; padding: 0; border: none; border-radius: 10px; background: none; cursor: pointer; }
.custom-colour .hex { width: 110px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; padding: 8px 10px; border: 1px solid #d8d3ca; border-radius: 10px; }
.custom-colour .hex.invalid { border-color: #e0453b; background: #fff3f2; }
.custom-colour .chip { font-size: 13px; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--ink); background: var(--ink); color: #fff; cursor: pointer; }
.custom-colour .tiny { flex-basis: 100%; }
.warn { color: #b25a00; }

/* Shape picker: five silhouettes per building type, same price, purely taste. */
.shape-picker { margin-top: 14px; }
.shape-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 7px; }
.shape-head b { font-size: 13.5px; }
.shape-head span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shape-row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 7px; }
.shape { border: 2px solid var(--line); border-radius: 12px; padding: 6px 4px 7px; background: #fff; display: grid; gap: 3px; justify-items: center; font-size: 11px; font-weight: 500; color: #454b58; transition: border-color 0.15s, box-shadow 0.15s; min-width: 0; }
.shape:hover { border-color: #c8ccd4; }
.shape.active { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(224,69,59,0.12); color: var(--ink); font-weight: 700; }
.shape-art { display: block; width: 100%; height: 46px; background: linear-gradient(180deg, #e6f1fa, #f2f7fb); border-radius: 8px; }
.shape-art svg { width: 100%; height: 100%; display: block; }
.shape span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
@media (max-width: 760px) { .shape-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* The sum written out under a total: plot + building + extras = what you pay. */
.calc { margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--line); font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.calc b { color: var(--ink); }
.type-card .calc { border-top: 0; padding-top: 2px; margin-top: 2px; font-size: 11px; line-height: 1.35; }

/* Floors chosen right at the tower, with a number field, steppers and presets. */
.floor-picker { margin-top: 14px; padding: 12px 14px; border: 2px solid var(--line); border-radius: 14px; background: #fbfbfc; }
/* The height ladder: one card per height a tower can be sold at, the price on the card. Used both in
   the checkout and in the owner area, so the two always look and read the same. */
.height-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; margin: 10px 0; }
.height-opt { display: flex; flex-direction: column; align-items: center; padding: 11px 6px 10px; border: 1.5px solid var(--line); border-radius: 12px; background: #fff; color: var(--ink); cursor: pointer; text-align: center; transition: border-color .12s ease, background .12s ease; }
.height-opt b { font-size: 20px; font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums; }
.height-opt span { font-size: 11px; color: var(--muted); }
.height-opt em { margin-top: 5px; font-style: normal; font-size: 12.5px; font-weight: 700; color: #454b58; }
.height-opt:hover { border-color: #c8ccd4; }
.height-opt.active { border-color: var(--accent); background: #fff4f2; box-shadow: inset 0 0 0 1px var(--accent); }
.height-opt.active em { color: var(--accent); }
.floor-total { margin: 2px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.floor-total b { color: var(--ink); }

/* Upgrade drawer: the honest saving for skipping a step, and the pill that repeats it on the card. */
.skip-deal { background: #fdf3e3; border: 1px solid #eccf95; border-radius: 10px; padding: 9px 12px; margin: 0 0 12px; font-size: 12.5px; line-height: 1.45; }
.skip-deal b { color: #8a5a10; }
.save-pill { display: inline-block; margin: 4px 0 0; padding: 2px 8px; border-radius: 999px; background: #2f9e44; color: #fff; font-size: 11px; font-weight: 700; letter-spacing: .02em; }
/* Package card: the piece-by-piece price struck through beside the package price. */
.price s { color: var(--muted); font-weight: 500; margin-right: 6px; text-decoration-thickness: 2px; }
.flag.deal { background: #2f9e44; color: #fff; }
.type-card .flag.free { background: #2f9e44; color: #fff; }

/* Short description: a real text box, with the room left shown under it. */
#wz-form textarea, .drawer textarea { width: 100%; box-sizing: border-box; font: inherit; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; resize: vertical; min-height: 68px; background: #fff; color: inherit; }
#wz-form textarea:focus, .drawer textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.counter { display: block; text-align: right; margin-top: 3px; }

/* A description of up to 500 characters needs room to breathe and a ceiling on the card. */
.slogan { line-height: 1.5; max-height: 8.2em; overflow-y: auto; white-space: pre-wrap; }

/* City design revision. Existing templates, IDs, modal states and actions stay
   compatible; these overrides style the city chrome without replacing page HTML. */
#city { cursor: grab; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
#city[data-navigating="true"] { cursor: grabbing; }
.topbar { padding-inline: clamp(18px, 2.4vw, 40px); box-shadow: 0 1px 0 var(--line); }
.brand { font-size: clamp(22px, 2.25vw, 34px); letter-spacing: -0.035em; }
.topbar nav { gap: 12px; }
.topbar .btn { min-height: 46px; padding-inline: 22px; border-radius: 10px; }
.hero { top: calc(var(--top) + 34px); left: 32px; max-width: min(600px, calc(100vw - 390px)); color: #fff; }
/* The dark wash existed to keep the white headline readable over the city. With the headline gone it
   would just be a smudge next to the counter, so it goes with it. */
.hero h1 { font-size: clamp(34px, 3.1vw, 52px); letter-spacing: -.045em; line-height: 1.08;
  text-wrap: balance; text-shadow: 0 2px 8px rgba(10, 20, 28, .25); }
.hero p { font-size: 19px; line-height: 1.45; margin: 10px 0 18px; text-shadow: 0 1px 5px rgba(10, 20, 28, .35); }
.hero .pill { color: var(--ink); background: #fff; font-size: 15px; padding: 11px 18px; box-shadow: var(--shadow-sm); }
.hero .pill b { color: #24763e; }

/* ---------- the free-house counter (Max, 17.9.2026) ----------
   The first fifty houses are free and the city says out loud how many are left. Red, big and above
   the built-count pill, because it is the only number on the page with a deadline attached to it.
   It is hidden until the numbers arrive and hidden again at zero, so it can never advertise an
   offer that has already ended. */
.freebar { pointer-events: none; max-width: 430px; margin-bottom: 12px; padding: 14px 18px 12px;
  border-radius: 16px; background: #fff; border: 2px solid #e11d2f; box-shadow: 0 12px 30px rgba(225, 29, 47, .22); }
.freebar[hidden] { display: none; }
.freebar-head { display: flex; align-items: baseline; gap: 9px; color: #9f0f1c; }
.freebar-head b { font-size: 46px; line-height: .95; font-weight: 800; letter-spacing: -.045em;
  color: #e11d2f; font-variant-numeric: tabular-nums; }
.freebar-head span { font-size: 16px; font-weight: 700; letter-spacing: -.015em; }
.freebar-head i { font-style: normal; }
.narrow-only { display: none; }
.freebar-track { height: 7px; border-radius: 999px; background: #f7dde0; overflow: hidden; margin: 10px 0 8px; }
.freebar-track i { display: block; height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, #e11d2f, #ff6a4d); transition: width .6s ease; }
.freebar small { display: block; font-size: 13px; line-height: 1.35; color: var(--muted); }
.freebar small span { color: #b3101f; font-weight: 700; }
/* The ring countdown sits under the offer, separated by a hairline rather than by a gap, so the
   card reads as one object. It replaces the old "x of 30,000 built" pill: the total made the city
   look like it had room forever, which is the opposite of what every other number here says. */
.freebar-ring { margin: 10px 0 0; padding-top: 9px; border-top: 1px solid #f1e3e5;
  font-size: 13.5px; font-weight: 600; color: var(--ink); }
.freebar-ring:empty { display: none; }
/* While the offer runs the ring panel on the right steps aside, so the hero card is the only thing
   over the city. ui.js sets the attribute; this rule outranks the positioning rules further down. */
.district-panel[hidden] { display: none; }
/* Under ten left the number breathes. Motion is the cheapest way to say "this is running out", and
   it switches itself off for anyone who has asked the system for less movement. */
.freebar.urgent .freebar-head b { animation: freepulse 1.6s ease-in-out infinite; }
@keyframes freepulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .freebar.urgent .freebar-head b { animation: none; } }

/* ---------- paid entry after the founding fifty ----------
   The city itself remains the hero image. This card simply puts a concrete, low-risk offer beside
   it once the giveaway is over, with the three objections answered before the visitor reaches the
   checkout: recurring cost, setup effort and ownership. */
/* Slim ring-progress ticker (Max, 20.9.2026): title/CTA/benefits removed on request, only the
   availability line and a thin progress bar. */
.paid-pitch { pointer-events: auto; width: min(360px, calc(100vw - 36px)); padding: 15px 16px 14px;
  border: 1px solid rgba(255,255,255,.18); border-radius: 14px; color: #d4dee7;
  background: rgba(10, 23, 40, .78); backdrop-filter: blur(6px);
  display: flex; flex-direction: column; gap: 11px; font-weight: 400; }
/* The headline of the tile, not a footnote any more (Max, 20.9.2026: "ruhig doppelt so hoch"). */
.paid-pitch #paid-remaining { color: #fff; font-size: 16px; font-weight: 700; line-height: 1.25;
  letter-spacing: -.02em; }
.paid-cta { display: flex; align-items: baseline; justify-content: center; gap: 8px; width: 100%;
  min-height: 42px; padding: 10px 14px; border: 0; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 700; letter-spacing: -.01em;
  color: #fff; background: var(--accent); transition: background .15s, transform .15s; }
.paid-cta:hover { background: #c9372c; }
.paid-cta:active { transform: translateY(1px); }
.paid-cta:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.paid-cta b { font-weight: 700; opacity: .92; white-space: nowrap; }
.paid-cta b:empty { display: none; }
.paid-pitch #paid-progress { display: block; width: 100%; height: 4px; border: 0; border-radius: 4px;
  overflow: hidden; background: rgba(255,255,255,.14); accent-color: #81d9bc; }
.paid-pitch #paid-progress::-webkit-progress-bar { background: rgba(255,255,255,.14); border-radius: 4px; }
.paid-pitch #paid-progress::-webkit-progress-value { background: #81d9bc; border-radius: 4px; }

@media (max-width: 760px) {
  .paid-pitch { width: min(320px, calc(100vw - 24px)); padding: 11px 13px 11px; border-radius: 12px; gap: 8px; }
  .paid-pitch #paid-remaining { font-size: 14px; }
  .paid-cta { min-height: 38px; padding: 8px 12px; font-size: 13px; gap: 6px; }
  .paid-pitch #paid-progress { height: 3px; }
}
.panel { border: 1px solid rgba(255, 255, 255, .85); }
.district-panel { top: calc(var(--top) + 30px); right: 30px; width: 292px; padding: 22px; }
.district-panel .headline { font-size: 27px; line-height: 1.15; letter-spacing: -.03em; margin-block: 12px; }
.district-panel .btn { min-height: 46px; }
.eyebrow { font-size: 12px; letter-spacing: .055em; }
.ringbar { height: 6px; }
.ringbar i { background: var(--accent); }
.district-bar { bottom: max(24px, env(safe-area-inset-bottom)); border-radius: 14px; padding: 6px;
  border: 1px solid rgba(255, 255, 255, .9); gap: 0; background: #fff; }
.district-bar button { min-height: 46px; border-radius: 9px; font-size: 14px; padding: 10px 18px; }
.district-bar button + button { margin-left: 4px; }
.district-bar button.active { background: #fff0ec; color: var(--accent); }
.district-bar button.active em { color: #a23b2e; }
.district-bar button:focus-visible { outline-offset: -3px; }
.tooltip { border: 1px solid var(--line); background: #fff; padding: 16px; border-radius: 14px; font-size: 14px; }
.tooltip b { font-size: 17px; }
.tooltip .tt-cta { padding: 9px 14px; font-size: 14px; }
.ticker { padding: 16px; }
.ticker .valuelist { gap: 6px; }
/* Pointer users navigate directly. Keep the existing controls reachable by
   keyboard focus as an accessible alternative without visible corner clutter. */
.viewport-tools { opacity: 0; pointer-events: none; transform: translateY(8px); }
.viewport-tools:focus-within { opacity: 1; pointer-events: auto; transform: none; }
.hint-bar { display: none; }
@media (min-width: 761px) and (max-width: 1180px) {
  .hero { max-width: calc(100vw - 375px); left: 24px; }
  .hero h1 { font-size: 36px; }
  .district-panel { right: 24px; }
  .ticker { bottom: 96px; max-height: max(100px, calc(100dvh - var(--top) - 340px)); }
}
@media (max-width: 760px) {
  :root { --top: 62px; }
  .topbar { padding-inline: 14px; gap: 10px; }
  .brand { font-size: 21px; }
  .topbar nav { gap: 0; }
  .topbar .btn { min-height: 42px; padding-inline: 13px; }
  .hero { left: 18px; right: 18px; top: calc(var(--top) + 20px); max-width: 460px; }
  .hero h1 { font-size: clamp(27px, 5.5vw, 34px); }
  .hero p { font-size: 16px; margin: 8px 0 12px; }
  .hero .pill { font-size: 14px; padding: 9px 13px; }
  .freebar { max-width: none; padding: 11px 14px 10px; border-radius: 14px; margin-bottom: 10px; }
  .freebar-head b { font-size: 34px; }
  .freebar-head span { font-size: 14px; }
  .freebar-track { height: 6px; margin: 8px 0 6px; }
  .freebar small { font-size: 12px; }
  .freebar-ring { font-size: 12.5px; margin-top: 8px; padding-top: 7px; }
  .district-panel { top: auto; bottom: calc(86px + env(safe-area-inset-bottom)); left: 14px; right: 14px;
    width: auto; padding: 14px 16px; max-height: 28dvh; overflow-y: auto; overscroll-behavior: contain; }
  .district-panel .headline { font-size: 21px; margin: 7px 0 10px; }
  .district-bar { left: 14px; right: 14px; bottom: calc(14px + env(safe-area-inset-bottom));
    transform: none; width: auto; max-width: none; }
  .district-bar button { font-size: 14px; padding: 10px 13px; min-height: 44px; }
  .tooltip { max-width: min(270px, calc(100vw - 32px)); }
  .sheet { max-height: calc(100dvh - 32px); }
}
@media (max-width: 430px) {
  .brand { font-size: 17px; }
  .topbar { padding-inline: 12px; gap: 8px; }
  .topbar .btn { font-size: 13px; padding-inline: 10px; }
}
@media (max-height: 540px) and (orientation: landscape) {
  .hero { max-width: 46vw; top: calc(var(--top) + 12px); }
  .hero h1 { font-size: 26px; }
  .hero p { font-size: 14px; margin-block: 6px; }
  .hero .pill { padding: 7px 11px; font-size: 13px; }
  .freebar { padding: 8px 12px; margin-bottom: 8px; }
  .freebar-head b { font-size: 26px; }
  .freebar-track, .freebar small { display: none; }
  .freebar-ring { margin-top: 6px; padding-top: 5px; font-size: 12px; }
  .district-panel { left: auto; right: 14px; top: calc(var(--top) + 12px); bottom: auto;
    width: 240px; max-height: calc(100dvh - var(--top) - 96px); padding: 14px; }
  .district-panel .headline { font-size: 20px; }
  .ticker { display: none; }
}

/* ===========================================================================
   Mobile pass (Max, 12.9.2026: "auf dem handy ziemlich voll und lieblos").
   Comes last on purpose so it wins over both earlier mobile blocks without
   rewriting them. Three goals, in this order:
   1. the checkout card was genuinely broken, not just tight
   2. give the city back the screen: chrome was eating 56 % of a 390x844 phone
   3. make the white hero text readable over pale pavement
   =========================================================================== */
@media (max-width: 760px) {

  /* --- the broken card ---------------------------------------------------
     The earlier rule made the card a two-column grid and then let all six
     children auto-flow into it, so the floors badge landed beside the tagline
     and the feature list beside the price. Everything is placed explicitly
     now: thumbnail left across two rows, name and badge stacked beside it,
     and every block of running text across the full width where it belongs. */
  .type-card { display: grid; grid-template-columns: 76px minmax(0, 1fr);
    column-gap: 13px; row-gap: 2px; align-items: start; padding: 15px 14px 14px; }
  .type-card .thumb { grid-column: 1; grid-row: 1 / span 2; height: 76px; margin: 0; align-self: center; }
  .type-card b { grid-column: 2; grid-row: 1; align-self: end; font-size: 16.5px; }
  /* justify-self, or the pill stretches to the full grid column and reads as a banner. */
  .type-card .floors-badge { grid-column: 2; grid-row: 2; align-self: start; justify-self: start; margin: 4px 0 0; }
  .type-card small,
  .type-card ul,
  .type-card .price,
  .type-card .calc { grid-column: 1 / -1; }
  .type-card small { margin: 9px 0 0; font-size: 13.5px; }
  .type-card ul { margin: 9px 0 0; font-size: 13px; gap: 4px; }
  .type-card .price { margin-top: 11px; font-size: 23px; display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
  .type-card .calc { margin-top: 7px; font-size: 12.5px; line-height: 1.45; }
  .type-card .flag { top: -10px; left: 14px; }

  /* A sticky bar that cuts text off mid-word reads as a rendering fault. The
     shadow says "this floats above the page" instead. */
  .wizard-foot { box-shadow: 0 -12px 22px -14px rgba(16, 20, 34, 0.5); }
  .wizard-body { padding-bottom: 4px; }

  /* The upsell had its checkbox, its heading, its six-line description and its
     price fighting over one flex row. Checkbox and heading share the top line
     with the price on the right, the description runs the full width below. */
  .bump { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 11px; row-gap: 2px; align-items: baseline; }
  .bump input { grid-row: 1; align-self: center; margin: 0; }
  .bump b { grid-row: 1; grid-column: 2; }
  .bump .bump-price { grid-row: 1; grid-column: 3; margin: 0; }
  .bump small { grid-column: 2 / -1; margin-top: 4px; }

  /* --- strip the phone back to what is needed (Max, 12.9.2026) ----------
     On a phone the city IS the pitch. The headline, the paragraph, the ring
     panel and the district nav all said things the map already shows, and
     together they covered more than half the screen.
     The headline stays in the document for search engines and screen readers,
     it is only taken out of the picture: a page with no h1 at all is a real
     SEO and accessibility loss, and hiding it costs nothing. */
  .hero h1 { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .hero p { display: none; }
  .hero { top: calc(var(--top) + 12px); }
  .hero .pill { font-size: 13.5px; padding: 9px 15px; box-shadow: var(--shadow); }
  .district-panel, .district-bar { display: none; }

  /* --- building card ----------------------------------------------------
     Four stacked label/value pairs were 186px of a phone screen for four
     short facts, and the three actions each wrapped onto two lines. */
  .facts { grid-template-columns: 1fr 1fr; gap: 13px 16px; }
  .facts dd { font-size: 15px; }
  .resident-head .avatar { width: 58px; height: 58px; border-radius: 13px; }
  #modal-building .row.gap { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  #modal-building .row.gap .btn { padding: 11px 8px; font-size: 13.5px; min-height: 44px; }
  #modal-building .row.gap .btn:first-child { grid-column: 1 / -1; }
}

@media (max-width: 430px) {
  /* The footer hint is guidance, not instruction. Below this width it costs
     the primary button the room it needs to stay on one line, which is the
     more expensive loss. */
  #wz-foot-hint { display: none; }
  .wizard-foot { gap: 8px; }
  .wizard-foot .row { width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; }
  .wizard-foot .row .btn-ghost { padding-inline: 16px; }
  .wizard-foot .row .btn-primary,
  .wizard-foot .row .btn-pay { width: 100%; padding-inline: 12px; font-size: 15px; }

  .type-card { grid-template-columns: 68px minmax(0, 1fr); column-gap: 11px; }
  .type-card .thumb { height: 68px; }
  .type-card b { font-size: 15.5px; }
  .type-card .price { font-size: 21px; }

  .hero p { font-size: 14.5px; margin: 8px 0 11px; }
}

/* ---------- consent banner ---------- */
/* Sits above everything including the checkout overlay (z-index 70): it has to be answerable
   whatever else is open, and it is the first thing a first-time visitor sees. */
.consent {
  /* Sits clear of the legal footer in the bottom-left corner. A consent banner that covers the
     imprint link makes the imprint unreachable while it is open, which is its own legal problem
     (§ 5 DDG), so the banner keeps its distance and carries the links itself as well. */
  position: fixed; left: 16px; right: 16px; bottom: 34px; z-index: 90;
  max-width: 640px; margin: 0 auto;
  display: flex; align-items: center; gap: 20px;
  padding: 18px 20px;
  background: var(--panel); backdrop-filter: blur(10px);
  border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-lg);
}
.consent-text { min-width: 0; }
.consent-text b { font-size: 15px; }
.consent-text p { margin: 5px 0 0; font-size: 13.5px; line-height: 1.45; color: var(--muted); }
.consent-text a { color: var(--accent); }
/* Equal weight on purpose: a decline that is harder to find than an accept is not a valid consent. */
.consent-actions { display: flex; gap: 8px; flex-shrink: 0; }
.consent-actions .btn { padding: 10px 18px; font-size: 14.5px; }
/* Both consent buttons look exactly alike on purpose. Consent is only free if refusing is as
   inviting as agreeing, so neither one gets the accent colour (EDPB 03/2022 on dark patterns). */
.btn-consent { background: #fff; color: var(--ink); border: 1.5px solid #c9ced9; font-weight: 600; min-width: 116px; }
.btn-consent:hover { background: #f3f5f9; border-color: #9aa4bf; }

@media (max-width: 620px) {
  .consent { flex-direction: column; align-items: stretch; gap: 14px; padding: 16px; }
  .consent-actions .btn { flex: 1; }
}

/* ===========================================================================
   The value board on the phone (Max, 17.9.2026: "auf dem handy dann ebenfalls
   die top 3 zu sehen ist aber man direkt drauf klicken kann").
   Comes last so it wins over the two earlier blocks that hid the panel
   outright. The live feed stays hidden: three rows is what a phone has room
   for, and the feed was the part that made the screen feel crowded.
   =========================================================================== */
@media (max-width: 760px) {
  /* The counter on the phone is a headline and one small line, nothing else: "7/50 free buildings
     left" and under it what happens afterwards. The bar, the reassurance sentence and the ring
     countdown are all true and all worth saying on a desktop, but stacked on a phone they turned a
     three-word message into a paragraph (Max, 17.9.2026). */
  .wide-only { display: none; }
  .narrow-only { display: inline; }
  .freebar { padding: 11px 14px 12px; }
  .freebar-head { gap: 0; align-items: baseline; }
  .freebar-head b { font-size: 27px; }
  .freebar-head span { font-size: 14.5px; }
  .freebar-track, .freebar-ring { display: none; }
  .freebar small { font-size: 12.5px; margin-top: 5px; }

  .ticker { display: block; left: 12px; right: 12px; width: auto; max-height: none; overflow: visible;
    bottom: calc(34px + env(safe-area-inset-bottom)); padding: 10px 12px 11px; }
  .ticker .feed-head, .ticker #ticker-list { display: none; }
  .ticker .eyebrow { font-size: 10.5px; }
  /* Folded the board shows three companies, unfolded it shows about six and scrolls through the
     rest (Max, 18.9.2026). The height is in dvh so it can never eat the whole screen on a small
     phone, and the row count is not hard-coded anywhere: three is a CSS rule, the rest is height. */
  .board-toggle { cursor: pointer; min-height: 30px; display: flex; align-items: center; gap: 6px; }
  .board-toggle .chev { display: block; margin-left: auto; width: 9px; height: 9px; border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor; transform: rotate(-135deg) translate(-2px, -2px); transition: transform .18s ease; }
  .board-toggle[aria-expanded="true"] .chev { transform: rotate(45deg) translate(-2px, -2px); }
  /* Closed the board is one line: the company at the top of the city and what it is worth. That is
     the whole message, and it leaves the phone screen to the city (Max, 18.9.2026). */
  body:not(.board-open) .valuelist li:nth-child(n+2) { display: none; }
  body.board-open .valuelist { max-height: 40dvh; overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin; padding-right: 7px; }
  .valuelist { margin-top: 7px; gap: 3px; }
  .valuelist li { padding: 6px; margin: 0; gap: 8px; }
  .valuelist li .mark { width: 32px; height: 32px; }
  .valuelist .who b { font-size: 14px; }
  /* No domain and no "value" label on a phone: the row has to stay one line tall, and the name and
     the figure are the two things worth the space. Tapping the row opens the building anyway. */
  .valuelist .who em, .valuelist .worth em { display: none; }
  .valuelist .worth b { font-size: 16px; }
  /* The legal line sits at the very bottom, so the board stops above it. */
  .legal { z-index: 12; }
}

.tower-compare-link { padding: 12px 0 0; color: #9ee2cb; text-align: left; font-size: 11px; text-decoration: underline; text-underline-offset: 3px; }
.tower-comparison { width: min(850px, calc(100vw - 28px)); max-width: 850px; }
.tower-comparison h2 { margin-top: 10px; }
.tower-comparison select { display: block; width: 100%; margin-top: 6px; padding: 10px; border: 1px solid #dce1e5; border-radius: 10px; background: #fff; }
.tower-compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 14px; }
.tower-compare-grid section { background: #eef3f4; padding: 12px; border-radius: 16px; }
.tower-compare-grid section:last-child { background: #e1eee9; }
.tower-compare-grid canvas { width: 100%; height: 240px; display: block; touch-action: none; }
.tower-compare-grid h3 { font-size: 18px; }
.tower-compare-grid p { font-size: 12px; line-height: 1.5; }
@media(max-width: 600px) { .tower-compare-grid { gap: 8px; } .tower-compare-grid canvas { height: 175px; } .tower-compare-grid h3 { font-size: 15px; } }
/* A quiet two-column frame leaves the centre of the city open. */
.paid-layout .hero { left: auto; right: 24px; top: calc(var(--top) + 24px); max-width: 360px; }
.paid-layout .ticker { top: calc(var(--top) + 24px); bottom: auto; left: 24px; width: 285px; max-height: calc(100dvh - var(--top) - 85px); padding: 16px 12px; background: #ffffffed; }
.paid-layout .valuelist li { padding: 8px 3px; gap: 8px; }
.paid-layout .valuelist .mark { width: 34px; height: 34px; }
.paid-layout .valuelist .who b { font-size: 12px; }
.paid-layout .valuelist .who em { font-size: 10px; }
.paid-layout .valuelist .worth b { font-size: 13px; }
/* Brought back small (Max, 19.9.2026: "wer als letztes eingezogen ist... in klein"): the compact
   card only has room for the last few move-ins, not the full mixed feed (duels, floor purchases,
   ring openings) the launch-phase ticker shows. ui.js filters to move_in events and caps at 4
   whenever .paid-layout is active; the sizing here just keeps those four lines as small as the
   rest of this card. */
/* display set explicitly, not just sizing: a separate, unconditional mobile rule
   (".ticker .feed-head, .ticker #ticker-list { display: none; }" further up) hides both below
   760px regardless of paid-layout, and this needs to win back over it at equal specificity by
   coming later in the file. */
.paid-layout .feed-head { display: block; margin-top: 9px; padding-top: 8px; font-size: 10px; }
.paid-layout #ticker-list { display: grid; gap: 4px; font-size: 11px; }
.paid-layout #ticker-list li i { width: 7px; height: 7px; }
.paid-layout #ticker-list li em { font-size: 10px; }
@media(max-width: 1000px) and (min-width: 761px) {
  .paid-layout .hero { right: 16px; max-width: 300px; }
  .paid-layout .ticker { left: 16px; width: 235px; }
}
/* Phone layout for the slim ticker (Max, 20.9.2026): one line plus a thin bar, sits top-left small. */
@media(max-width: 760px) {
  .paid-layout .hero { left: 12px; right: auto; top: calc(var(--top) + 10px); max-width: min(300px, calc(100vw - 24px)); }
  .paid-layout .ticker { top: auto; bottom: 28px; left: 12px; width: min(300px, calc(100vw - 110px)); max-height: 25dvh; padding: 10px; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
  .paid-layout .valuelist li { padding: 4px 0; }
  .paid-layout .feed-head { margin-top: 6px; padding-top: 6px; }
  .paid-layout #ticker-list { gap: 3px; }
  .paid-layout .district-bar { display: none; }
}

/* ===========================================================================
   The value board, in the same material as the paid pitch (Max, 18.9.2026:
   "die Karte, die jetzt die Liste zeigt, soll auch aufwendiger sein").
   Same dark glass, same restraint: one white line per company, the domain
   under it in grey, the figure in mint so the eye lands on money, and the
   brand red kept for the first three ranks so the card still reads as ours.
   Last block in the file on purpose, so it wins over the light panel rules
   above without any of them having to be rewritten.
   =========================================================================== */
.ticker, .paid-layout .ticker {
  background: rgba(16, 29, 42, .94); border: 1px solid rgba(255, 255, 255, .09);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 18px 44px rgba(9, 17, 26, .34); color: #e7eef5;
}
.ticker .eyebrow, .ticker .board-toggle { color: #f0b64a; }
.ticker .eyebrow .crown { color: #f0b64a; }

.valuelist li { border-color: transparent; }
.valuelist li:hover { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .12); }
.valuelist li .no { background: rgba(255, 255, 255, .11); color: #9db1c2; }
.valuelist li:nth-child(-n+3) .no { background: var(--accent); color: #fff; }
/* The logo tiles stay white: a company mark belongs on its own background, not on ours. */
.valuelist li .mark { background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); }
.valuelist .who b { color: #fff; }
.valuelist .who em { color: #8ea3b6; }
.valuelist .worth b { color: #7ee3ae; }
.valuelist .worth em { color: #7b8fa1; }

/* The live feed underneath, same treatment. */
.ticker .feed-head { border-top-color: rgba(255, 255, 255, .12); }
.ticker ul li { color: #c6d4e1; }
.ticker ul li:hover { color: #7ee3ae; }
.ticker ul li em { color: #8093a5; }
.ticker li.muted, .ticker .muted { color: #93a7b9; }
.ticker li .mark.initials { box-shadow: none; }
