@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("vendor/inter/InterVariable.woff2") format("woff2");
}

:root {
  color-scheme: dark;
  interpolate-size: allow-keywords;

  /* Ink and surfaces */
  --ink: #f7f2dc;
  --muted: #aaa792;
  --surface: #12130f;
  --surface-soft: #090a08;
  --surface-raised: #181914;
  --border: #343328;
  --border-strong: #4b4938;

  /* Gold */
  --brand: #f4c542;
  --brand-bright: #ffd95a;
  --brand-deep: #d7a91e;
  --on-brand: #090a08;

  /* Gluten-free levels. Single source of truth: js/app.js reads these
     at runtime so map dots and legend dots can never drift apart. */
  --dedicated: #2bb673;
  --menu: #5aa8e6;
  --options: #df8f1f;
  --candidate: #a582d8;
  --danger: #ef8078;

  --shadow: 0 18px 48px rgb(0 0 0 / 48%);

  /* Layering. .map-region must never create a stacking context, so these
     values compete globally and can sit above .search-panel. */
  --z-overlay: 10;
  --z-panel: 20;
  --z-legend: 25;
  --z-status: 30;
  --z-popup: 40;

  /* Motion */
  --ease: cubic-bezier(.2, .7, .3, 1);
  --dur-fast: 140ms;
  --dur: 240ms;
  --dur-slow: 620ms;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--surface-soft);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-optical-sizing: auto;
  font-synthesis-weight: none;
}

/* The map page is a fixed three-row frame; the legal pages scroll normally. */
body.app {
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  overflow: hidden;
}

button, input, select { font: inherit; }

button, a { -webkit-tap-highlight-color: transparent; }

.topbar {
  min-height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 10px 20px;
  color: var(--ink);
  border-bottom: 1px solid #3b3420;
  background: linear-gradient(115deg, #050604, #0d0e0b 58%, #1b180d);
  box-shadow: 0 8px 28px rgb(0 0 0 / 52%);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: inherit;
  text-decoration: none;
}

.brand-mark {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  color: var(--on-brand);
  border: 2px solid var(--brand-bright);
  border-radius: 50% 50% 50% 14%;
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .03em;
  background: linear-gradient(145deg, var(--brand-bright), var(--brand-deep));
  box-shadow: 0 0 24px rgb(244 197 66 / 20%);
  transition: box-shadow var(--dur) var(--ease);
}

.brand:hover .brand-mark { box-shadow: 0 0 30px rgb(244 197 66 / 42%); }

.brand strong, .brand small { display: block; }
.brand strong { font-size: 1.1rem; font-weight: 700; letter-spacing: -.015em; }
.brand small { margin-top: 2px; opacity: .84; font-size: .75rem; }

.topbar-actions { display: flex; align-items: center; gap: 10px; }

.project-link {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  padding: 7px 12px;
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 999px;
  text-decoration: none;
  font-size: .78rem;
  font-weight: 700;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}

.project-link:hover, .project-link:focus-visible { color: var(--on-brand); border-color: var(--brand); background: var(--brand); }

.language-toggle {
  min-height: 38px;
  padding: 7px 12px;
  color: var(--brand-bright);
  border: 1px solid rgb(244 197 66 / 52%);
  border-radius: 999px;
  background: rgb(244 197 66 / 8%);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}

.language-toggle:hover, .language-toggle:focus-visible { color: var(--on-brand); background: var(--brand); }

.app-shell {
  min-height: 0;
  position: relative;
  overflow: hidden;
  background: #050604;
}

.search-panel {
  width: min(340px, calc(100% - 32px));
  max-height: calc(100% - 36px);
  position: absolute;
  z-index: var(--z-panel);
  top: 18px;
  left: 18px;
  overflow: auto;
  padding: 19px 17px;
  border: 1px solid rgb(244 197 66 / 28%);
  border-radius: 18px;
  background: rgb(13 14 11 / 91%);
  box-shadow: 0 24px 70px rgb(0 0 0 / 58%);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
}

.field + .field { margin-top: 18px; }

.field label {
  display: block;
  margin-bottom: 7px;
  font-size: .82rem;
  font-weight: 650;
}

.search-row { display: flex; }

input, select {
  width: 100%;
  min-height: 43px;
  color: var(--ink);
  border: 1px solid var(--border-strong);
  border-radius: 9px;
  background: var(--surface-raised);
  transition: border-color var(--dur-fast) var(--ease);
}

input { padding: 9px 12px; border-radius: 9px 0 0 9px; }
select { padding: 8px 34px 8px 11px; }

input:hover, select:hover { border-color: #6b6850; }

input:focus, select:focus, button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 3px solid rgb(244 197 66 / 32%);
  outline-offset: 2px;
}

.search-row button {
  width: 45px;
  flex: 0 0 45px;
  color: var(--on-brand);
  border: 0;
  border-radius: 0 9px 9px 0;
  background: var(--brand);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.search-row button:hover { background: var(--brand-bright); }

.result-count { margin: 20px 0 8px; font-weight: 700; font-variant-numeric: tabular-nums; }
.data-notice { margin: 0; color: var(--muted); font-size: .78rem; line-height: 1.45; }
.data-mode { display: grid; gap: 7px; margin: 16px 0 0; padding: 11px; border: 1px solid #59436f; border-radius: 10px; background: #1b1422; }
.data-mode[hidden] { display: none; }
.data-mode legend { padding: 0 4px; font-size: .78rem; font-weight: 800; }
.data-mode label { display: flex; align-items: center; gap: 8px; font-size: .78rem; font-weight: 650; }
.data-mode input { width: 17px; min-height: 17px; accent-color: #8c62ba; }
.data-mode small { color: #b7a8c5; font-size: .69rem; line-height: 1.35; }

.map-region { position: absolute; inset: 0; min-width: 0; }
#map { width: 100%; height: 100%; background: radial-gradient(circle at 58% 44%, #2b2717, #090a08 52%, #020302); }
#map canvas { cursor: grab; }
#map canvas:active { cursor: grabbing; }

.globe-intro {
  position: absolute;
  z-index: var(--z-overlay);
  top: 24px;
  /* Anchored to the right edge of the search panel so the two can never overlap. */
  left: calc(18px + min(340px, 100% - 32px) + 18px);
  max-width: min(340px, calc(100% - 420px));
  display: grid;
  gap: 3px;
  padding: 11px 14px;
  color: var(--ink);
  border: 1px solid rgb(244 197 66 / 14%);
  border-radius: 12px;
  background: rgb(7 8 6 / 72%);
  box-shadow: 0 12px 35px rgb(0 0 0 / 20%);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  pointer-events: none;
}
.globe-intro strong { font-size: clamp(.9rem, 1.4vw, 1.1rem); font-weight: 650; letter-spacing: -.01em; }
.globe-intro small { color: var(--muted); font-size: .7rem; }

/* Kept as an alias of .eyebrow for the existing markup hook. */
.globe-kicker {
  color: var(--brand);
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.legend {
  position: absolute;
  z-index: var(--z-legend);
  right: 58px;
  bottom: 30px;
  display: grid;
  gap: 7px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgb(13 14 11 / 91%);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--shadow);
  font-size: .75rem;
}

.legend > span { display: flex; align-items: center; gap: 7px; }
.legend-dot { width: 10px; height: 10px; border-radius: 50%; }
.legend-dot.dedicated_kitchen { background: var(--dedicated); }
.legend-dot.gf_menu { background: var(--menu); }
.legend-dot.gf_options { background: var(--options); }
.legend-dot.candidate { background: var(--candidate); }

.loading-state {
  position: absolute;
  z-index: var(--z-status);
  top: 18px;
  left: 50%;
  padding: 9px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow);
  transform: translateX(-50%);
  font-size: .82rem;
}

/* Gold sweep along the pill while data is in flight. */
.loading-state::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(100deg, transparent 20%, rgb(244 197 66 / 75%) 50%, transparent 80%) 0 0 / 250% 100%;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  animation: sweep 1.6s linear infinite;
  pointer-events: none;
}

.loading-state[hidden] { display: none; }
.loading-state.error { color: var(--danger); border-color: rgb(239 128 120 / 45%); }
.loading-state.error::after { animation: none; opacity: 0; }

.venue-popup { width: min(310px, 72vw); }
.venue-popup h2 { margin: 0 0 7px; font-size: 1.13rem; font-weight: 650; letter-spacing: -.015em; }
.venue-location { margin: 0 0 10px; color: var(--muted); }
.venue-native-name { margin: -4px 0 10px; color: var(--muted); font-size: .84rem; }

/* Two tiers, so the reader can tell the claim from its provenance:
   the gluten-free level is one loud filled chip, everything about
   how it was verified is a quiet outlined chip. All clear WCAG AA. */
.gf-badge, .status-badge, .verification-badge {
  display: inline-block;
  margin: 0 5px 10px 0;
  padding: 5px 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 800;
}

/* Tier 1 — the claim. Dark ink on a saturated fill. */
.gf-badge { color: var(--on-brand); }
.gf-badge.dedicated_kitchen { background: var(--dedicated); }
.gf-badge.gf_menu { background: var(--menu); }
.gf-badge.gf_options { background: var(--options); }
.gf-badge.candidate { background: var(--candidate); }

/* Tier 2 — the provenance. Outlined, never competing with tier 1. */
.status-badge, .verification-badge {
  font-weight: 700;
  background: transparent;
  border-color: currentcolor;
}
.status-badge { color: #c5c0a8; }
.verification-badge.primary_source { color: #9fd0f0; }
.verification-badge.certified_current { color: #4dd598; }
.verification-badge.community { color: #f2d47a; }
.verification-badge.stale, .verification-badge.conflicting { color: var(--danger); }

.popup-facilities {
  margin-top: .7rem;
  padding: .65rem .7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-soft);
  font-size: .78rem;
}
.popup-facilities summary { cursor: pointer; font-weight: 650; }
.popup-facilities ul, .popup-sources ul { margin: .45rem 0 0; padding-left: 1.25rem; }

.popup-row { margin: 7px 0; font-size: .8rem; line-height: 1.4; }
.popup-row strong { display: block; }

.popup-links { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
.popup-links a, .reviews-button {
  display: inline-flex;
  align-items: center;
  min-height: 33px;
  padding: 6px 9px;
  color: var(--brand-bright);
  border: 1px solid #5f532b;
  border-radius: 7px;
  background: #1c1b13;
  text-decoration: none;
  cursor: pointer;
  font-size: .76rem;
  font-weight: 650;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}

.popup-links a:hover, .reviews-button:hover:not(:disabled) {
  color: var(--on-brand);
  border-color: var(--brand);
  background: var(--brand);
}

.popup-sources {
  margin-top: .8rem;
  padding-top: .65rem;
  border-top: 1px solid var(--border);
}

.popup-sources summary {
  color: var(--brand-bright);
  cursor: pointer;
  font-weight: 650;
}

.popup-sources ol { margin: .45rem 0 0; padding-left: 1.4rem; }
.popup-sources li + li { margin-top: .25rem; }

/* Disclosure widgets open by height instead of snapping.
   Browsers without ::details-content simply drop these rules. */
.popup-facilities::details-content, .popup-sources::details-content {
  height: 0;
  overflow: hidden;
  transition: height var(--dur) var(--ease), content-visibility var(--dur) allow-discrete;
}
.popup-facilities[open]::details-content, .popup-sources[open]::details-content { height: auto; }

.reviews-panel { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--border); }
.review { margin-top: 9px; padding-top: 9px; border-top: 1px dashed var(--border); font-size: .76rem; }
.review p { margin: 4px 0; }
.review-author { font-weight: 700; }
.review-author a { color: var(--brand-bright); }

.disclaimer {
  margin: 12px 0 0;
  padding: 9px;
  color: #f4d98b;
  border-left: 4px solid var(--options);
  background: #2a210f;
  font-size: .76rem;
  font-weight: 650;
  line-height: 1.35;
}
.candidate-warning { margin: 12px 0 0; padding: 9px; color: #d7c2ed; border-left: 4px solid #8c62ba; background: #21172b; font-size: .76rem; font-weight: 650; line-height: 1.35; }

.footer {
  min-height: 36px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 18px;
  color: var(--muted);
  background: var(--surface);
  border-top: 1px solid var(--border);
  font-size: .72rem;
}

.footer a { color: var(--brand-bright); transition: color var(--dur-fast) var(--ease); }
.footer a:hover { color: var(--brand); }
.footer nav { display: flex; align-items: center; gap: 14px; }

.legal-page {
  min-height: 100%;
  padding: 28px 18px;
  background: var(--surface-soft);
}

.legal-content {
  width: min(760px, 100%);
  margin: 0 auto;
  padding: clamp(22px, 5vw, 48px);
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow);
  line-height: 1.65;
}

.legal-content h1 { margin: 1.2rem 0 .5rem; line-height: 1.15; font-weight: 700; letter-spacing: -.022em; }
.legal-content h2 { margin: 1.65rem 0 .35rem; font-size: 1.15rem; font-weight: 650; letter-spacing: -.012em; }
.legal-content p { margin: .45rem 0; }
.legal-content a { color: var(--brand-bright); }
.legal-content hr { margin: 2.2rem 0; border: 0; border-top: 1px solid var(--border); }

.contribution-page form { display: grid; gap: 8px; margin-top: 20px; }
.contribution-page form > label:not(.consent-row) { margin-top: 9px; font-weight: 650; }
.contribution-page textarea { width: 100%; padding: 10px 12px; resize: vertical; color: var(--ink); border: 1px solid var(--border-strong); border-radius: 9px; background: var(--surface-raised); font: inherit; transition: border-color var(--dur-fast) var(--ease); }
.contribution-page textarea:hover { border-color: #6b6850; }
.contribution-page textarea:focus { outline: 3px solid rgb(244 197 66 / 32%); outline-offset: 2px; }
.review-target { display: grid; gap: 3px; margin: 18px 0; padding: 12px 14px; border-left: 4px solid #8c62ba; background: #21172b; }
.review-target span { color: var(--muted); font-size: .82rem; }
.consent-row { display: flex; align-items: flex-start; gap: 9px; margin: 12px 0; font-size: .85rem; }
.consent-row input { width: 18px; min-height: 18px; flex: 0 0 auto; }
.primary-action { min-height: 44px; padding: 9px 14px; color: var(--on-brand); border: 0; border-radius: 9px; background: var(--brand); cursor: pointer; font-weight: 800; transition: background-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease); }
.primary-action:hover { background: var(--brand-bright); }
.primary-action:active { transform: translateY(1px); }
.form-notice { margin-top: 16px; padding: 10px; color: var(--muted); background: var(--surface-soft); font-size: .8rem; }

.maplibregl-popup-content { max-height: min(68vh, 620px); overflow: auto; padding: 15px; color: var(--ink); border: 1px solid #48442e; border-radius: 14px; background: rgb(18 19 15 / 97%); box-shadow: var(--shadow); }
/* Must clear .search-panel, which overlays the map at top left.
   Never animate transform on .maplibregl-popup itself: MapLibre positions it
   with an inline transform, and an animation overrides inline styles, so a
   filling keyframe would strand the popup at the map origin. The entrance
   animation goes on the content element, which MapLibre does not position. */
.maplibregl-popup { z-index: var(--z-popup); }
.maplibregl-popup-content { animation: popup-in var(--dur) var(--ease) both; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-right .maplibregl-popup-tip { border-bottom-color: #12130f; }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip { border-top-color: #12130f; }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: #12130f; }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: #12130f; }
.maplibregl-popup-close-button { width: 30px; height: 30px; border-radius: 50%; font-size: 20px; }
.maplibregl-ctrl-group { overflow: hidden; border: 1px solid rgb(244 197 66 / 30%); border-radius: 10px; background: #151610; box-shadow: 0 8px 24px rgb(0 0 0 / 48%); }
.maplibregl-ctrl-group button { background-color: #151610; transition: background-color var(--dur-fast) var(--ease); }
.maplibregl-ctrl-group button:hover { background-color: #272516; }
.maplibregl-ctrl-icon { filter: invert(89%) sepia(49%) saturate(777%) hue-rotate(342deg) brightness(102%); }
.maplibregl-ctrl-attrib { color: var(--muted); border-radius: 6px 0 0; background: rgb(9 10 8 / 82%) !important; }
.maplibregl-ctrl-attrib a { color: #e2c65e; }

/* ---------------------------------------------------------------------------
   Globe ignition. One orchestrated sequence, once per load.

   [data-boot] is set inline in <head> before first paint, so the panels are
   only ever hidden when the script that reveals them is guaranteed to run.
   app.js sets [data-globe-ready] when the globe finishes initialising, with a
   timeout fallback so a failed map can never leave the page blank.
--------------------------------------------------------------------------- */

/* .map-region is deliberately NOT animated. Any animation on it that touches
   opacity creates a stacking context which traps the MapLibre popup inside,
   putting it behind .search-panel with no way to lift it out. The panels
   carry the sequence on their own. */
@keyframes rise-left { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
@keyframes rise-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ignite {
  0% { box-shadow: 0 0 0 rgb(244 197 66 / 0%); }
  55% { box-shadow: 0 0 40px rgb(244 197 66 / 55%); }
  100% { box-shadow: 0 0 24px rgb(244 197 66 / 20%); }
}
@keyframes sweep { to { background-position: -250% 0; } }
@keyframes popup-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

html[data-boot] .search-panel,
html[data-boot] .globe-intro,
html[data-boot] .legend { opacity: 0; }

body[data-globe-ready="true"] .search-panel { animation: rise-left 460ms var(--ease) 180ms both; }
body[data-globe-ready="true"] .globe-intro { animation: fade-in 460ms var(--ease) 300ms both; }
body[data-globe-ready="true"] .legend { animation: rise-up 460ms var(--ease) 380ms both; }
body[data-globe-ready="true"] .brand-mark { animation: ignite 900ms var(--ease) 520ms both; }

@media (max-width: 900px) {
  .globe-intro { left: 18px; top: auto; bottom: 30px; max-width: min(340px, calc(100% - 120px)); }
}

@media (max-width: 760px) {
  .topbar { min-height: 62px; padding: 8px 12px; }
  .brand small { display: none; }
  .topbar-actions { gap: 6px; }
  .project-link { padding: 7px 9px; font-size: .7rem; }
  .language-toggle { font-size: .75rem; }
  .app-shell { min-height: 540px; }
  .search-panel { width: calc(100% - 20px); max-height: 43%; top: 10px; left: 10px; padding: 10px 12px; border-radius: 14px; display: grid; grid-template-columns: 1.4fr 1fr; gap: 9px; }
  .field + .field { margin-top: 0; }
  .field label { font-size: .72rem; }
  input, select { min-height: 39px; font-size: .82rem; }
  .result-count { grid-column: 1 / -1; margin: 0; font-size: .75rem; }
  .data-mode { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; padding: 7px 9px; }
  .data-mode legend, .data-mode small { display: none; }
  .data-notice { display: none; }
  .globe-intro { top: auto; right: auto; bottom: 30px; left: 10px; max-width: calc(100% - 120px); padding: 8px 10px; }
  .globe-intro strong, .globe-intro small { display: none; }
  .legend { right: 48px; bottom: 28px; padding: 8px; }
  .legend strong { display: none; }
  .footer { padding: 0 10px; }
  .footer nav { gap: 8px; }
  .footer nav a:last-child { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .loading-state::after { opacity: 0; }
  html[data-boot] .search-panel,
  html[data-boot] .globe-intro,
  html[data-boot] .legend { opacity: 1; }
}
