/* e-oberrad — structure borrowed from trustmrr (mono type, 8px radius, hairline
   borders, 9px micro-labels, tight 9/12/14/16/30 scale), colour is our own:
   a warm neutral shell + one herb-green accent, with a categorical ramp reserved
   strictly for map markers and category chips. Shell stays quiet, colour means something. */

@font-face {
  font-family: Inconsolata;
  src: url(font/inconsolata.woff2) format('woff2-variations');
  font-weight: 400 700;
  font-display: swap;
}

:root {
  --paper:  oklch(0.972 0.006 85);
  --card:   oklch(1 0 0);
  --ink:    oklch(0.165 0.008 75);
  --muted:  oklch(0.555 0.012 75);
  --line:   oklch(0.912 0.008 85);
  --accent: oklch(0.505 0.125 148);      /* herb green — Grüne Soße, the Kräuterfelder */
  --accent-ink: oklch(0.985 0 0);

  /* categorical ramp — markers + chips only, never the shell */
  --c-food:     oklch(0.62 0.15 45);
  --c-shops:    oklch(0.56 0.13 305);
  --c-health:   oklch(0.58 0.17 22);
  --c-kids:     oklch(0.68 0.15 85);
  --c-nature:   oklch(0.53 0.13 150);
  --c-sport:    oklch(0.56 0.13 245);
  --c-services: oklch(0.55 0.02 260);
  --c-transit:  oklch(0.60 0.10 195);
  --c-fest:     oklch(0.58 0.17 350);

  --r: 8px;
  --shadow: 0 1px 2px rgb(0 0 0 / .05);
  --tap: 44px;
}

/* Dark: warm charcoal, not black — the shell stays the quiet part. The
   categorical ramp lifts in lightness so markers keep their meaning against a
   dark map instead of turning to mud. JS stamps data-theme on <html> from the
   saved choice, or from prefers-color-scheme when there is none. */
:root[data-theme="dark"] {
  --paper:  oklch(0.205 0.008 75);
  --card:   oklch(0.253 0.008 75);
  --ink:    oklch(0.945 0.005 85);
  --muted:  oklch(0.700 0.012 80);
  --line:   oklch(0.335 0.008 75);
  --accent: oklch(0.680 0.135 148);
  --accent-ink: oklch(0.175 0.01 75);

  --c-food:     oklch(0.74 0.14 45);
  --c-shops:    oklch(0.72 0.13 305);
  --c-health:   oklch(0.71 0.16 22);
  --c-kids:     oklch(0.79 0.14 85);
  --c-nature:   oklch(0.70 0.13 150);
  --c-sport:    oklch(0.71 0.12 245);
  --c-services: oklch(0.70 0.02 260);
  --c-transit:  oklch(0.74 0.10 195);
  --c-fest:     oklch(0.72 0.16 350);

  --shadow: 0 1px 2px rgb(0 0 0 / .4);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  padding-bottom: calc(72px + env(safe-area-inset-bottom));
  background: var(--paper);
  color: var(--ink);
  font: 400 16px/1.5 Inconsolata, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -.4px; }
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 45%, transparent); border-radius: 6px; }

.wrap { width: 100%; max-width: 1080px; margin-inline: auto; padding-inline: 16px; }

/* ── micro-label: the single most load-bearing detail ── */
.micro {
  font-size: 9px; font-weight: 600; line-height: 1.5;
  text-transform: uppercase; letter-spacing: .45px; color: var(--muted);
}

/* ── header ── */
.top {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in oklch, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.top-in { display: flex; align-items: center; justify-content: space-between; height: 52px; }
/* The arms and the name are two different destinations, so they get a gap you
   can aim at and a hairline between them — otherwise it reads as one word and
   whichever half you hit feels like a misfire. */
.brand { display: flex; align-items: center; gap: 13px; color: var(--ink); }
/* Oberrad's coat of arms, the Commons SVG as-is. */
.brand-arms {
  display: grid; place-items: center; width: 28px; height: 28px;
  margin-left: -4px; border-radius: 8px; text-decoration: none;
  transition: background .15s;
}
.brand-arms:hover { background: color-mix(in oklch, var(--ink) 8%, transparent); }
.brand-mark { width: 15px; height: 16px; display: block; }
.brand-name {
  position: relative; border: 0; background: none; cursor: pointer;
  padding: 5px 2px; color: var(--ink);
  font-weight: 700; font-size: 14px; letter-spacing: 1.4px;
}
.brand-name::before {
  content: ''; position: absolute; left: -7px; top: 50%;
  width: 1px; height: 15px; margin-top: -7.5px; background: var(--line);
}
.brand-name:hover { text-decoration: underline; text-underline-offset: 4px; }
.top-right { display: flex; align-items: center; gap: 10px; }
.today { font-size: 12px; font-weight: 500; color: var(--muted); }
/* No colour of their own. They are settings, not destinations — a raised card
   against the flat header is enough to find them, and it leaves the accent
   green to mean one thing on this site instead of three. */
.lang {
  font-size: 12px; font-weight: 700; letter-spacing: .3px;
  border: 1.5px solid var(--line); border-radius: 999px;
  min-height: 32px; padding: 0 12px;
  background: var(--card); color: var(--ink);
  box-shadow: 0 1px 2px rgb(0 0 0 / .05);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.lang:hover {
  background: color-mix(in oklch, var(--ink) 6%, var(--card));
  border-color: color-mix(in oklch, var(--ink) 22%, var(--line));
}
/* Square, not a pill. It holds one glyph, and side padding on a single
   character stretches into a lozenge as soon as the screen is wide. */
#theme {
  width: 32px; padding: 0;
  font-size: 15px; line-height: 1;
}

/* ── search ── */
.searchbar { padding-top: 12px; }
.field { position: relative; }
.field-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; fill: none; stroke: var(--muted); stroke-width: 2;
  stroke-linecap: round; pointer-events: none;
}
#q {
  width: 100%; height: 40px; padding: 0 36px 0 36px;
  font-size: 16px;                     /* 16px on mobile or iOS zooms on focus */
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); outline: none;
  transition: border-color .15s, box-shadow .15s;
  -webkit-appearance: none;
}
#q::placeholder { color: var(--muted); }
#q::-webkit-search-cancel-button { display: none; }
#q:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 40%, transparent); }
.field-clear {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 6px; font-size: 18px; color: var(--muted);
}
.field-clear:hover { color: var(--ink); }

/* ── section headers ── */
.sec { display: flex; align-items: baseline; justify-content: space-between; margin: 26px 0 10px; }
.sec-h { font-size: 14px; font-weight: 700; }
.sec-note { font-size: 12px; font-weight: 500; color: var(--muted); }
.sec-link {
  font-size: 12px; font-weight: 500; color: var(--muted); text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px; transition: color .15s;
}
.sec-link:hover { color: var(--ink); }        /* colour only — nothing moves */

/* ── up next banner ── */
.upnext {
  margin-top: 14px; padding: 14px;
  border: 1px solid color-mix(in oklch, var(--c-fest) 28%, var(--line));
  background: color-mix(in oklch, var(--c-fest) 7%, var(--card));
  border-radius: 12px;
}
.upnext-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.upnext-title { font-size: 16px; font-weight: 700; margin: 4px 0 2px; }
.upnext-when { font-size: 12px; color: var(--muted); }
.countdown {
  flex: none; font-size: 12px; font-weight: 700; padding: 4px 9px; border-radius: 999px;
  color: var(--c-fest); background: color-mix(in oklch, var(--c-fest) 14%, var(--card));
}

/* ── horizontal scroll-snap rows ── */
.row {
  display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: 4px; margin-inline: -16px; padding-inline: 16px;
  scrollbar-width: none;
}
.row::-webkit-scrollbar { display: none; }
.row > * { scroll-snap-align: start; flex: 0 0 auto; }

.mcard {
  width: 168px; padding: 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--card); box-shadow: var(--shadow);
}
.mcard.is-now { border-color: var(--accent); background: color-mix(in oklch, var(--accent) 6%, var(--card)); }
.mcard-m { font-size: 14px; font-weight: 700; margin-bottom: 6px; }
.mcard ul { margin: 0 0 6px; padding-left: 14px; }
.mcard ul:last-child { margin-bottom: 0; }
.mcard li { font-size: 12px; color: var(--muted); line-height: 1.55; }
/* Events read as the headline of the month; crops carry the herb colour so a
   glance separates "what is in the ground" from "what is on". */
.mcard-ev li { color: var(--ink); }
.mcard-ev li::marker { color: var(--accent); }
.mcard-grow li::marker { color: var(--c-nature); }
.mcard .micro { margin-bottom: 2px; }

.season { display: grid; gap: 12px; }
.seasongroup .micro { margin-bottom: 6px; }
.pills { display: flex; flex-wrap: wrap; gap: 6px; }
.upnext.neutral {
  border-color: color-mix(in oklch, var(--accent) 26%, var(--line));
  background: color-mix(in oklch, var(--accent) 6%, var(--card));
}
.upnext.neutral .countdown { color: var(--accent); background: color-mix(in oklch, var(--accent) 13%, var(--card)); }
.pill {
  font-size: 12px; font-weight: 500; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--muted);
}
.pill.grow { color: var(--c-nature); border-color: color-mix(in oklch, var(--c-nature) 30%, var(--line)); }

/* ── chips ── */
.chips {
  display: flex; gap: 6px; overflow-x: auto; padding: 12px 16px 12px;
  margin-inline: -16px; scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--muted);
  transition: color .15s, border-color .15s, background .15s;
}
.chip:hover { color: var(--ink); }
.chip .dot { width: 7px; height: 7px; border-radius: 999px; background: var(--dot, var(--muted)); }
.chip[aria-pressed="true"] {
  color: var(--ink); background: color-mix(in oklch, var(--dot, var(--ink)) 10%, var(--card));
  border-color: color-mix(in oklch, var(--dot, var(--ink)) 40%, var(--line));
}

/* ── list controls ── */
.listbar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.count { font-size: 12px; font-weight: 500; color: var(--muted); margin-right: auto; }
.nearme {
  font-size: 12px; font-weight: 500; padding: 7px 10px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--card); color: var(--muted);
  box-shadow: var(--shadow); transition: color .15s, border-color .15s;
}
.nearme:hover { color: var(--ink); border-color: var(--muted); }
.sortwrap select {
  font-size: 12px; font-weight: 500; padding: 7px 10px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  box-shadow: var(--shadow); -webkit-appearance: none; appearance: none;
}

/* ── place cards ── */
.cards { display: grid; gap: 10px; grid-template-columns: 1fr; }
.pcard {
  display: block; width: 100%; text-align: left; padding: 12px;
  border-radius: 12px; border: 1px solid var(--line); background: var(--card);
  box-shadow: var(--shadow); transition: border-color .15s, transform .06s;
}
.pcard:hover { border-color: color-mix(in oklch, var(--cat, var(--muted)) 45%, var(--line)); }
.pcard:active { transform: scale(.995); }
.pcard-top { display: flex; align-items: flex-start; gap: 10px; }
/* Keeps the category colour the dot carried, now as the tint behind the glyph. */
.pcard-ico {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; margin-top: 1px;
  font-size: 15px; line-height: 1; border-radius: 9px;
  background: color-mix(in oklch, var(--cat) 16%, var(--card));
  border: 1px solid color-mix(in oklch, var(--cat) 32%, var(--line));
}
.pcard-name { font-size: 14px; font-weight: 700; line-height: 1.35; }
.pcard-type { font-size: 12px; color: var(--muted); }
.pcard-stats {
  display: flex; gap: 18px; margin-top: 10px; padding-top: 9px;
  border-top: 1px dashed var(--line);       /* dashed strip separator, per trustmrr */
}
.pcard-val { font-size: 12px; font-weight: 700; }
.pcard-val.open { color: var(--accent); }
.pcard-val.shut { color: var(--muted); }

.more {
  width: 100%; margin-top: 14px; height: 40px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--card); font-size: 14px; font-weight: 500;
  box-shadow: var(--shadow); transition: border-color .15s;
}
.more:hover { border-color: var(--muted); }
.empty { padding: 32px 0; text-align: center; font-size: 14px; color: var(--muted); }

/* ── map ── */
.mapbox {
  position: relative; border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; background: var(--card); box-shadow: var(--shadow);
  height: min(62vh, 520px);
}
.map-holder { width: 100%; height: 100%; touch-action: none; cursor: grab; }
.map-holder:active { cursor: grabbing; }
.map-holder svg { display: block; width: 100%; height: 100%; }

#built    polygon { fill: color-mix(in oklch, var(--muted) 9%, var(--paper)); stroke: none; }
#fields   polygon { fill: color-mix(in oklch, var(--c-kids) 16%, var(--paper)); stroke: none; }
#forest   polygon { fill: color-mix(in oklch, var(--c-nature) 20%, var(--paper)); stroke: none; }
/* ── walks, rides and parks ─────────────────────────────── */
.routes { display: grid; gap: 12px; margin-bottom: 22px; }
.rcard {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); overflow: hidden;
}
.rphoto { margin: 0; }
.rphoto img {
  display: block; width: 100%; height: 168px; object-fit: cover;
  background: color-mix(in oklch, var(--muted) 12%, var(--paper));
}
/* The card shows a crop. The corner mark is the only hint needed that the
   whole photo is one tap away. */
.rphoto-link { display: block; position: relative; cursor: zoom-in; }
.rphoto-zoom {
  position: absolute; right: 8px; bottom: 8px;
  width: 26px; height: 26px; border-radius: 7px;
  display: grid; place-items: center;
  font-size: 12px; line-height: 1;
  background: color-mix(in oklch, black 55%, transparent);
  color: #fff; backdrop-filter: blur(3px);
  opacity: .85; transition: opacity .15s;
}
.rphoto-link:hover .rphoto-zoom { opacity: 1; }

/* Not a photo, so it does not get the zoom cursor or the crop treatment. */
.rphoto-ph { display: block; width: 100%; height: 100%; object-fit: cover; }

/* The one control in the header that goes somewhere rather than changing a
   setting, so it is the only one carrying the accent. */
.topnav {
  border-color: color-mix(in oklch, var(--accent) 40%, var(--line));
  color: color-mix(in oklch, var(--accent) 85%, var(--ink));
  background: color-mix(in oklch, var(--accent) 8%, var(--card));
}
.topnav:hover {
  background: color-mix(in oklch, var(--accent) 16%, var(--card));
  border-color: var(--accent);
}

/* ── stories ── */
.stories { display: grid; gap: 14px; }
.scard {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card); overflow: hidden;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05);
}
/* Taller than the route band: these are portraits and old prints, and a thin
   strip of a painting tells you nothing. */
.sphoto { margin: 0; position: relative; }
.sphoto .rphoto-link { height: 210px; }
.sphoto img { width: 100%; height: 210px; object-fit: cover; display: block; }
/* An 1815 aquatint and a painted portrait are not photographs — showing the
   whole plate matters more than filling the band edge to edge. */
.scard[data-fit="whole"] .sphoto img { object-fit: contain; background: color-mix(in oklch, var(--ink) 5%, var(--paper)); }
.sbody { padding: 13px 14px 15px; }
.stitle { font-size: 15px; line-height: 1.35; margin: 5px 0 7px; font-weight: 700; }
.stext { font-size: 13px; line-height: 1.65; color: var(--ink); margin: 0; }
.slink {
  display: inline-block; margin-top: 9px;
  font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: .45px;
  color: var(--muted);
}
@media (min-width: 720px) { .stories { grid-template-columns: repeat(2, 1fr); } }

/* ── photo page ── */
.photopage { padding: 4px 0 24px; }
.pback {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 38px; padding: 0 14px 0 10px; margin-bottom: 14px;
  border: 1.5px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05);
  transition: background .15s, border-color .15s;
}
.pback:hover {
  background: color-mix(in oklch, var(--ink) 6%, var(--card));
  border-color: color-mix(in oklch, var(--ink) 22%, var(--line));
}
.pback-i { font-size: 19px; line-height: 1; margin-top: -2px; }
/* Fit the whole photo, never crop — the entire point of this page. The height
   cap keeps a tall portrait shot from pushing the credit off the screen. */
.pimg {
  display: block; width: 100%; max-height: 78vh;
  object-fit: contain; border-radius: var(--r);
  background: color-mix(in oklch, var(--ink) 6%, var(--paper));
}
.pcap { font-size: 13px; line-height: 1.6; color: var(--ink); margin: 12px 0 4px; }
/* The tab bar would sit on top of a landscape photo on a short screen. */
body.on-photo .tabs { position: static; }

/* ── suggestion board ── */
.suggest {
  margin-top: 22px; padding: 16px;
  border: 1px solid color-mix(in oklch, var(--accent) 25%, var(--line));
  border-radius: var(--r);
  background: color-mix(in oklch, var(--accent) 5%, var(--card));
}
.suggest-p { font-size: 13px; line-height: 1.6; color: var(--muted); margin: 6px 0 12px; }
.suggest-btn {
  display: inline-flex; align-items: center; min-height: 38px; padding: 0 16px;
  border: 0; border-radius: 999px; background: var(--accent); color: var(--accent-ink);
  font-size: 13px; font-weight: 700; text-decoration: none; cursor: pointer;
}
.suggest-btn:hover { filter: brightness(1.08); }
.suggest-btn:disabled { opacity: .5; cursor: default; filter: none; }
.suggest .fineprint { margin-top: 10px; }

.board { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; }
.bitem {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
}
.bitem.done { opacity: .6; }
/* The vote is the whole point of the board, so it is the biggest target on
   the row and it holds its own count — no separate number to read. */
.bvote {
  flex: 0 0 auto; display: grid; place-items: center; gap: 0;
  width: 40px; padding: 5px 0; cursor: pointer;
  border: 1.5px solid var(--line); border-radius: 9px;
  background: var(--paper); color: var(--muted);
  transition: border-color .15s, background .15s, color .15s;
}
.bvote:hover { border-color: color-mix(in oklch, var(--accent) 45%, var(--line)); }
.bvote.on {
  background: color-mix(in oklch, var(--accent) 14%, var(--card));
  border-color: var(--accent); color: var(--accent);
}
.bcaret { font-size: 9px; line-height: 1; }
.bcount { font-size: 13px; font-weight: 700; line-height: 1.3; color: var(--ink); }
.bvote.on .bcount { color: var(--accent); }
.btext { min-width: 0; }
.btitle { display: block; font-size: 13px; font-weight: 600; line-height: 1.45; }
.bmeta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 3px;
  font-size: 9px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .45px; color: var(--muted);
}
.bbadge {
  padding: 1px 6px; border-radius: 999px;
  background: color-mix(in oklch, var(--sand) 22%, var(--card));
  color: color-mix(in oklch, var(--sand) 70%, var(--ink));
}
.bbadge.done { background: color-mix(in oklch, var(--accent) 18%, var(--card)); color: var(--accent); }
.bdetail { font-size: 12px; line-height: 1.55; color: var(--muted); margin: 5px 0 0; }

.bform { display: grid; gap: 10px; margin-top: 12px; }
.bfield { display: grid; gap: 4px; }
.blabel {
  font-size: 9px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .45px; color: var(--muted);
}
.binput {
  font: inherit; font-size: 13px; color: var(--ink);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 10px; min-height: 38px; width: 100%;
}
.binput:focus { outline: 2px solid color-mix(in oklch, var(--accent) 45%, transparent); outline-offset: 1px; }
textarea.binput { resize: vertical; line-height: 1.5; }
.brow { display: flex; align-items: center; gap: 12px; }
.blink {
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--muted); text-decoration: underline;
}
/* Off-screen rather than display:none — a bot that skips hidden fields would
   skip this one too, and then it is not a trap. */
.bpot { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.credit {
  padding: 5px 12px; font-size: 9px; font-weight: 600; line-height: 1.5;
  text-transform: uppercase; letter-spacing: .45px; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.credit a { color: inherit; }
.rbody { padding: 12px 14px 14px; }
.rtop { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.rbody h4 { margin: 0 0 2px; font-size: 16px; font-weight: 700; letter-spacing: -.3px; }
.rwhere { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.rbody p { margin: 0 0 8px; font-size: 14px; }
.rbody p:last-child { margin-bottom: 0; }
.todo {
  font-size: 12px; color: var(--muted);
  border-left: 2px solid color-mix(in oklch, var(--c-kids) 60%, var(--paper));
  padding-left: 8px;
}
.rlink { font-size: 12px; font-weight: 700; color: var(--accent); text-decoration: none; }
.rlink:hover { text-decoration: underline; }

@media (min-width: 720px) { .routes { grid-template-columns: repeat(2, 1fr); } }

/* ── about ──────────────────────────────────────────────── */
/* The header is sticky, so anything scrolled to with block:'start' lands
   underneath it. This is the whole fix for "the About section is hidden". */
.sec-h { scroll-margin-top: 66px; }
.about { margin-bottom: 22px; }
.facts {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; margin-bottom: 14px;
}
.fact { background: var(--card); padding: 9px 11px; }
.fact-v { font-size: 13px; font-weight: 700; letter-spacing: -.2px; }
.prose p { margin: 0 0 10px; font-size: 14px; }
.prose p:last-child { margin-bottom: 0; }

@media (min-width: 720px) {
  .facts { grid-template-columns: repeat(4, 1fr); }
  .prose { columns: 2; column-gap: 26px; }
  .prose p { break-inside: avoid; }
}

/* ── category overview tiles ────────────────────────────── */
.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 18px; }
.tile {
  text-align: left; padding: 12px; border-radius: var(--r); background: var(--card);
  border: 1px solid var(--line); box-shadow: var(--shadow); min-height: 92px;
  transition: border-color .15s, transform .12s;
}
.tile:hover { border-color: var(--cat); transform: translateY(-1px); }
.tile-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.tile-dot { width: 9px; height: 9px; border-radius: 999px; background: var(--cat); }
.tile-n { font-size: 18px; font-weight: 700; letter-spacing: -.6px; }
.tile-name { font-size: 14px; font-weight: 700; margin-bottom: 3px; }
.tile-eg {
  font-size: 11px; line-height: 1.45; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

@media (min-width: 720px) { .tiles { grid-template-columns: repeat(4, 1fr); } }

/* ── street search results ──────────────────────────────── */
.streets { margin-bottom: 12px; }
.streetrow { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.streetbtn {
  display: flex; flex-direction: column; gap: 1px; text-align: left;
  padding: 7px 11px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r);
  font-size: 13px; min-height: var(--tap);
}
.streetbtn:hover { border-color: color-mix(in oklch, var(--accent) 50%, var(--line)); }

#streetpin circle { fill: none; stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; }
#streetpin text {
  fill: var(--ink); font-weight: 700; text-anchor: middle;
  paint-order: stroke; stroke: var(--paper); stroke-width: 3px;
  vector-effect: non-scaling-stroke; pointer-events: none;
}

/* Parks read a shade stronger than forest so they stand out against it. */
#green    polygon { fill: color-mix(in oklch, var(--c-nature) 34%, var(--paper)); stroke: none; }
#sportarea polygon { fill: color-mix(in oklch, var(--c-sport) 22%, var(--paper)); stroke: none; }
#water    polyline { fill: none; stroke: color-mix(in oklch, var(--c-sport) 45%, white); stroke-width: 7; stroke-linecap: round; }
#roads-minor polyline { fill: none; stroke: var(--line); stroke-width: 1; }
#roads    polyline { fill: none; stroke: color-mix(in oklch, var(--muted) 40%, white); stroke-width: 2.2; stroke-linecap: round; }
#tram     polyline { fill: none; stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 5 4; opacity: .7; }
#maplabels text {
  fill: var(--muted); font-weight: 700; letter-spacing: .4px;
  text-anchor: middle; paint-order: stroke; stroke: var(--paper); stroke-width: 3px;
  vector-effect: non-scaling-stroke;   /* halo stays 3px however far we zoom */
  pointer-events: none; text-transform: uppercase;
}
#maplabels .big { fill: color-mix(in oklch, var(--ink) 70%, var(--paper)); }

/* Where Oberrad actually stops. Dashed, because a hard line would read as a
   wall and the neighbourhood does not feel like one. */
#border polyline {
  fill: none;
  stroke: color-mix(in oklch, var(--accent) 70%, var(--paper));
  stroke-width: 2.5; stroke-dasharray: 8 5; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
#highlights { transition: opacity .18s; }
#highlights circle {
  fill: var(--card); stroke: var(--ink); stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
#highlights text {
  fill: var(--ink); font-weight: 700; text-anchor: middle;
  paint-order: stroke; stroke: var(--paper); stroke-width: 3.5px;
  vector-effect: non-scaling-stroke; pointer-events: none;
}
/* The glyph sits in the middle of its own disc, so no halo and no outline —
   the stroke the name labels use would trace right around the emoji. */
#highlights text.hi-ico { stroke: none; dominant-baseline: central; }
#streetlabels text {
  fill: var(--muted); text-anchor: middle; font-weight: 600;
  paint-order: stroke; stroke: var(--paper); stroke-width: 3px;
  vector-effect: non-scaling-stroke; pointer-events: none;
}
.mk { cursor: pointer; }
/* Sits on the marker's own disc, so it needs no halo of its own. */
#markers .mk-ico { text-anchor: middle; dominant-baseline: central; pointer-events: none; }
#markers .has-ico circle { stroke: var(--card); stroke-width: 2; }
.mk circle { stroke: var(--card); stroke-width: 1.5; }
.mk.sel circle { stroke: var(--ink); stroke-width: 2; }

.map-ctl { position: absolute; right: 10px; bottom: 10px; display: grid; gap: 6px; }
.map-ctl button {
  width: 34px; height: 34px; border-radius: var(--r); border: 1px solid var(--line);
  background: var(--card); box-shadow: var(--shadow); font-size: 15px; line-height: 1;
  transition: border-color .15s;
}
.map-ctl button:hover { border-color: var(--muted); }
.map-legend {
  position: absolute; left: 10px; bottom: 10px; display: flex; flex-wrap: wrap; gap: 4px 8px;
  max-width: 62%; padding: 7px 9px; border-radius: var(--r);
  background: color-mix(in oklch, var(--card) 88%, transparent);
  border: 1px solid var(--line); backdrop-filter: blur(6px);
}
.map-legend span { display: inline-flex; align-items: center; gap: 4px; font-size: 9px;
  font-weight: 600; text-transform: uppercase; letter-spacing: .45px; color: var(--muted); }
.map-legend i { width: 7px; height: 7px; border-radius: 999px; }

/* ── detail sheet ── */
.sheet-bg { position: fixed; inset: 0; background: rgb(0 0 0 / .28); z-index: 40; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  max-height: 86vh; overflow-y: auto;
  padding: 16px 16px calc(20px + env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--line);
  border-radius: 16px 16px 0 0; box-shadow: 0 -8px 32px rgb(0 0 0 / .12);
  animation: rise .18s ease-out;
}
@keyframes rise { from { transform: translateY(14px); opacity: .6 } }
@media (prefers-reduced-motion: reduce) { .sheet { animation: none } }
.sheet-grab { width: 34px; height: 4px; border-radius: 999px; background: var(--line); margin: 0 auto 12px; }
.crumb { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.sheet h3 { font-size: 20px; letter-spacing: -.5px; }
/* Tinted with the category's own colour, so the sheet, the legend and the dot
   you just tapped all agree about what kind of place this is. */
.sheet-head { display: flex; align-items: center; gap: 11px; }
.sheet-ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 42px; height: 42px; font-size: 20px; line-height: 1;
  border-radius: 12px; border: 1.5px solid var(--line);
}
.statpills { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }
.statpill {
  font-size: 12px; font-weight: 500; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper); color: var(--muted);
}
.statpill.on { color: var(--accent); border-color: color-mix(in oklch, var(--accent) 35%, var(--line)); }
.acts { display: flex; gap: 8px; margin-top: 14px; }
.btn {
  flex: 1; height: 40px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border-radius: var(--r); font-size: 14px; font-weight: 500; text-decoration: none;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  box-shadow: var(--shadow); transition: border-color .15s, background .15s;
}
.btn:hover { border-color: var(--muted); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: color-mix(in oklch, var(--accent) 88%, black); }
.raw { font-size: 12px; color: var(--muted); margin-top: 12px; word-break: break-word; }

/* ── tabs ── */
.tabs {
  position: fixed; z-index: 30; left: 50%; transform: translateX(-50%);
  bottom: calc(10px + env(safe-area-inset-bottom));
  display: flex; gap: 2px; padding: 4px; border-radius: 999px;
  background: color-mix(in oklch, var(--card) 92%, transparent);
  border: 1px solid var(--line); box-shadow: 0 4px 20px rgb(0 0 0 / .10);
  backdrop-filter: blur(10px);
}
.tabs button {
  min-height: 36px; padding: 0 18px; border-radius: 999px;
  font-size: 12px; font-weight: 600; color: var(--muted);
  transition: color .15s, background .15s;
}
.tabs button:hover { color: var(--ink); }
.tabs button.on { color: var(--accent-ink); background: var(--ink); }

.fineprint { font-size: 12px; color: var(--muted); margin: 22px 0 8px; line-height: 1.6; }
.fineprint a { color: var(--muted); }
.fineprint a:hover { color: var(--ink); }

/* ── wider screens ── */
@media (min-width: 720px) {
  #q, .sortwrap select { font-size: 14px; }   /* 14px is safe once we're off mobile */
  .cards { grid-template-columns: repeat(2, 1fr); }
  /* Leave room under the map for the ODbL line — the floating tab pill would
     otherwise sit on top of it, and attribution has to stay readable. */
  .mapbox { height: min(62vh, 480px); }
}
@media (min-width: 1024px) {
  .cards { grid-template-columns: repeat(3, 1fr); }
  .mcard { width: 190px; }
}
