/* ==========================================================================
   Geography Art — the shared stylesheet.
   Evergreen for what you are making, bark brown for what is already made,
   white surfaces on an off-white ground. Every page loads this and one
   stylesheet of its own.
   ========================================================================== */

:root {
  --ink:        #1b2620;
  --ink-2:      #34443b;
  --muted:      #5d6b63;
  --line:       #dfe5df;
  --line-2:     #edf1ec;
  --surface:    #ffffff;
  --canvas:     #f6f7f3;

  --evergreen:      #1f5a32;
  --evergreen-700:  #16452a;
  --evergreen-tint: #e5efe6;

  --bark:      #7a4f2a;
  --bark-700:  #5b3a1e;
  --bark-tint: #f3ebe2;

  --ok:   #2f7d4f;
  --warn: #b7791f;
  --bad:  #b42318;

  --topbar-h: 60px;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;

  --shadow-1: 0 1px 2px rgba(27,38,32,.06), 0 1px 3px rgba(27,38,32,.04);
  --shadow-2: 0 4px 12px rgba(27,38,32,.08), 0 12px 32px rgba(27,38,32,.08);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

/* Several classes below set `display`, which would otherwise beat the UA's
   [hidden] rule and leave empty boxes on screen. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { color: var(--ink); line-height: 1.2; letter-spacing: -0.02em; margin: 0; }

a { color: var(--evergreen); text-underline-offset: 2px; }
a:hover { color: var(--evergreen-700); }

img { max-width: 100%; display: block; }

:focus-visible { outline: 2px solid var(--evergreen); outline-offset: 2px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -9999px; top: 8px; z-index: 100;
  background: var(--surface); padding: 10px 16px; border-radius: var(--r-sm);
  box-shadow: var(--shadow-2); font-weight: 600;
}
.skip-link:focus { left: 12px; }

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

/* ── Header ──────────────────────────────────────────────────────────── */

.topbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--topbar-h);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 0 clamp(16px, 4vw, 32px);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex; align-items: center; gap: 10px;
  color: var(--ink); text-decoration: none; font-weight: 700;
  letter-spacing: -0.02em; font-size: 17px; flex-shrink: 0;
}
.brand-mark { width: 30px; height: 30px; color: var(--evergreen); flex-shrink: 0; }
.brand:hover { color: var(--evergreen); }
/* A page's title sits between the brand and the link, centred in the space
   between them rather than on the page, so it never runs under either. */
.page-title { flex: 1; margin: 0; text-align: center; font-size: 16px; font-weight: 700; color: var(--evergreen); letter-spacing: -0.01em; }
.topbar nav { display: flex; align-items: center; gap: 4px; }
.topbar nav a {
  display: block; padding: 8px 14px; border-radius: 999px;
  font-size: 14.5px; font-weight: 600; color: var(--evergreen);
  text-decoration: none; white-space: nowrap;
}
.topbar nav a:hover { background: var(--evergreen-tint); color: var(--evergreen-700); }

/* ── Pages ───────────────────────────────────────────────────────────── */

/* A map page: the map fills everything under the header, one card floats on it. */
.panel-map {
  position: relative;
  height: calc(100dvh - var(--topbar-h));
  overflow: hidden;
}

.map-fallback, .map-error {
  position: absolute; inset: 0; display: grid; place-items: center;
  padding: 32px; text-align: center; color: var(--muted);
}

/* A text page: one column of prose. */
.prose { max-width: 680px; margin: 0 auto; padding: clamp(32px, 6vw, 72px) clamp(16px, 5vw, 40px) 96px; }
.prose h1 { font-size: clamp(28px, 5vw, 40px); font-weight: 700; letter-spacing: -0.03em; margin-bottom: 16px; }
.prose p { margin: 0 0 16px; }

.maplibregl-ctrl-group { border-radius: var(--r-sm) !important; box-shadow: var(--shadow-1) !important; }
.maplibregl-ctrl-attrib { font-size: 11px; }

/* ── The floating card ───────────────────────────────────────────────── */

.map-card {
  position: absolute; z-index: 10;
  top: 16px; left: 16px; width: 320px; max-width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  padding: 18px;
}

.readout {
  margin: 0 0 14px; display: grid; gap: 1px;
  background: var(--line-2); border-radius: var(--r-sm); overflow: hidden;
}
.readout > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  background: var(--surface); padding: 9px 12px;
}
.readout dt { font-size: 13px; color: var(--muted); }
.readout dd {
  margin: 0; font-size: 13.5px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; text-align: right;
}

.status {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 0 0 14px; font-size: 13px; line-height: 1.5; color: var(--ink-2);
  min-height: 20px;
}
.status-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  margin-top: 6px; background: var(--muted);
}
.status-dot[data-state="idle"]    { background: var(--line); }
.status-dot[data-state="loading"] { background: var(--evergreen); animation: pulse 1.2s ease-in-out infinite; }
.status-dot[data-state="ok"]      { background: var(--ok); }
.status-dot[data-state="warn"]    { background: var(--warn); }
.status-dot[data-state="bad"]     { background: var(--bad); }
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .3 } }

/* Source attribution. Both licences require it, so unlike other fine print
   it stays visible at every width. */
.attribution { margin: 14px 0 0; font-size: 11px; line-height: 1.55; color: var(--muted); }
.attribution a { color: var(--muted); text-decoration: underline; }
.attribution a:hover { color: var(--evergreen); }

/* ── Buttons ─────────────────────────────────────────────────────────── */

.primary-btn {
  display: inline-block; width: 100%; text-align: center;
  padding: 12px 20px; border: none; border-radius: var(--r-md);
  background: var(--evergreen); color: #fff;
  font-family: inherit; font-size: 15px; font-weight: 600;
  text-decoration: none; cursor: pointer;
  box-shadow: 0 1px 2px rgba(31,90,50,.28), 0 4px 12px rgba(31,90,50,.2);
  transition: background .16s ease, transform .1s ease;
}
.primary-btn:hover:not(:disabled) { background: var(--evergreen-700); color: #fff; transform: translateY(-1px); }
.primary-btn:active:not(:disabled) { transform: translateY(0); }
.primary-btn:disabled { background: var(--line); color: var(--muted); box-shadow: none; cursor: not-allowed; }

.ghost-btn {
  padding: 8px 14px; border-radius: var(--r-sm);
  background: transparent; border: 1px solid var(--line);
  color: var(--ink-2); font-family: inherit; font-size: 13.5px; font-weight: 550;
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease, color .16s ease;
}
.ghost-btn:hover { background: var(--canvas); border-color: var(--muted); color: var(--ink); }

/* ── A row of tabs inside a card (the Wine Atlas's modes) ────────────── */

.mode-switch {
  position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 2px; padding: 3px; margin-bottom: 14px;
  background: var(--canvas); border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.mode-btn {
  position: relative; z-index: 1;
  padding: 7px 10px; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--muted); border-radius: var(--r-sm);
  transition: color .16s ease;
}
.mode-btn:hover { color: var(--ink); }
.mode-btn[aria-selected="true"] { color: var(--ink); }

/* ── A card that holds a list and a detail view (wine, languages) ────── */

/* Taller than the print card because it holds a list, and capped so the list
   scrolls inside the card instead of the card growing past the viewport. */
.finder-card {
  width: 340px;
  max-height: calc(100dvh - var(--topbar-h) - 32px);
  display: flex; flex-direction: column;
  padding-bottom: 14px;
}

.finder-state-field {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: -2px 0 11px; color: var(--muted);
  font-size: 11px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase;
}
.finder-state-field select {
  flex: 1; min-width: 0; padding: 8px 30px 8px 10px;
  color: var(--ink); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); font: inherit; font-size: 13.5px;
  font-weight: 550; letter-spacing: 0; text-transform: none;
}
.finder-state-field select:focus {
  outline: none; border-color: var(--evergreen); box-shadow: 0 0 0 3px var(--evergreen-tint);
}

.finder-search { position: relative; display: block; margin-bottom: 12px; }
.finder-search svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--muted); pointer-events: none;
}
.finder-search input {
  width: 100%; padding: 10px 12px 10px 34px;
  font: inherit; font-size: 14.5px; color: var(--ink);
  background: var(--canvas);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.finder-search input:focus {
  outline: none; background: var(--surface);
  border-color: var(--evergreen);
  box-shadow: 0 0 0 3px var(--evergreen-tint);
}
/* Safari draws its own clear button on type=search and it collides with the
   card's padding at this width. */
.finder-search input::-webkit-search-decoration,
.finder-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.finder-list {
  list-style: none; padding: 0;
  overflow-y: auto; overscroll-behavior: contain;
  flex: 0 1 auto; max-height: 42dvh; min-height: 0;
  /* Bleeds past the card's padding so a row's hover fill runs the full width;
     the inset comes back on the row itself. */
  margin: 0 -6px;
}
.finder-list::-webkit-scrollbar { width: 8px; }
.finder-list::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }

.finder-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  width: 100%; padding: 8px 10px;
  background: none; border: 0; border-radius: var(--r-sm);
  font: inherit; text-align: left; color: var(--ink-2); cursor: pointer;
}
.finder-row:hover { background: var(--evergreen-tint); color: var(--ink); }
.finder-row-name { font-size: 14.5px; font-weight: 550; color: var(--ink); }
.finder-row-meta {
  font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.is-unmapped .finder-row-name { color: var(--ink-2); font-weight: 500; }

.finder-empty { padding: 10px; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

.finder-detail {
  display: flex; flex-direction: column; gap: 12px;
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 3px;
}
.finder-detail::-webkit-scrollbar { width: 7px; }
.finder-detail::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.finder-detail h3 { font-size: 20px; font-weight: 650; letter-spacing: -0.02em; margin: 0; }
.detail-meta { margin: 0; font-size: 13px; color: var(--muted); }

.finder-back {
  display: flex; align-items: center; gap: 4px;
  align-self: flex-start; padding: 4px 8px 4px 4px; margin: -4px 0 2px -4px;
  background: none; border: 0; border-radius: var(--r-sm);
  font: inherit; font-size: 13px; font-weight: 550; color: var(--muted);
  cursor: pointer;
}
.finder-back:hover { color: var(--evergreen); background: var(--evergreen-tint); }
.finder-back svg { width: 14px; height: 14px; }

.finder-card .attribution { margin-top: 12px; flex-shrink: 0; }

/* Every level's header is also its disclosure control: the name you are
   looking at is the thing you click to fold it away. Shared by the Languages
   Map's browse levels and the Ordinance Map's jurisdiction list. */
.card-section summary, .languages-analysis summary {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; cursor: pointer; list-style: none;
  font-size: 15px; font-weight: 650; letter-spacing: -0.01em; color: var(--ink);
}
.card-section summary::-webkit-details-marker,
.languages-analysis summary::-webkit-details-marker { display: none; }
.card-section summary:hover, .languages-analysis summary:hover { color: var(--evergreen); }
.card-section summary::after, .languages-analysis summary::after {
  content: ''; flex-shrink: 0; margin-left: auto;
  width: 7px; height: 7px; color: var(--muted);
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .15s ease;
}
.card-section[open] summary::after, .languages-analysis[open] summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

/* Sources sit behind a toggle: they matter, but not on every glance. Shared by
   the Languages Map and the Ordinance Map, which present the same kind of
   attribution block at the foot of the same kind of card. */
.card-sources { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 10px; }
.card-sources summary {
  cursor: pointer; color: var(--muted); font-size: 11px;
  font-weight: 650; letter-spacing: .07em; text-transform: uppercase;
}
.card-sources summary:hover { color: var(--ink-2); }
.card-sources .attribution { margin-top: 8px; }

/* In the Ordinance Map the card is a flex column whose list scrolls; the
   toggle must keep its own height instead of being squeezed by that list. */
.finder-card .card-sources { flex-shrink: 0; }
.finder-card .card-section { flex: 0 1 auto; min-height: 0; }

/* ── Small screens ───────────────────────────────────────────────────── */

@media (max-width: 720px) {
  :root { --topbar-h: 54px; }

  .topbar { gap: 12px; padding: 0 14px; }
  .brand-text { display: none; }
  .page-title { font-size: 15px; }

  /* The card becomes a bottom sheet so the map keeps the usable area. */
  .map-card {
    top: auto; bottom: 0; left: 0; right: 0;
    width: auto; max-width: none;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
    box-shadow: 0 -4px 24px rgba(27,38,32,.12);
  }

  /* Only the scale bar. The attribution control stays: it carries the
     basemap's OpenStreetMap credit. */
  .maplibregl-ctrl-scale { display: none; }

  /* The list gets a fixed share of the screen so the sheet can never grow to
     cover the map it is a legend for. */
  .finder-card { width: auto; max-height: 68dvh; }
  .finder-list { max-height: 30dvh; }
  .finder-detail { max-height: 46dvh; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
