/* ART WACO TX — style.css
   One stylesheet, no framework. Palette: gallery ivory, ink, Cameron Park green, river blue. */

:root {
  --ivory: #faf6ef;
  --ivory-deep: #f1eade;
  --ink: #221f1a;
  --ink-soft: #4d463c;
  --green: #3e6b4a;
  --green-deep: #2b5036;
  --teal: #33627f;
  --gold: #d9a441;
  /* The East Waco walk, added 8/22/26. 7.57:1 on the ivory ground and 8.16:1
     under white text — the same AA bar the palette was rebuilt to in August.
     Warm, but far enough from burnt orange not to reopen that argument. */
  --plum: #7a3b52;
  --card: #ffffff;
  --shadow: 0 2px 14px rgba(34, 31, 26, .10);
  --radius: 14px;
  --maxw: 1080px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  font-family: "Source Sans 3", -apple-system, "Segoe UI", sans-serif;
  background: var(--ivory);
  color: var(--ink);
  line-height: 1.6;
  font-size: 17px;
}

h1, h2, h3, .display {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  line-height: 1.15;
}

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

a { color: var(--teal); }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 1200;
  background: rgba(250, 246, 239, .94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(34,31,26,.08);
}
.site-header .bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 20px; max-width: var(--maxw); margin: 0 auto;
}
.logo {
  font-family: "Fraunces", serif; font-weight: 700; font-size: 1.35rem;
  color: var(--ink); text-decoration: none; letter-spacing: .5px;
}
.logo em { font-style: normal; color: var(--green); }
.nav a {
  color: var(--ink-soft); text-decoration: none; margin-left: 22px;
  font-weight: 600; font-size: .95rem;
}
.nav a:hover { color: var(--green); }
.nav a.cta {
  background: var(--green); color: #fff; padding: 8px 16px;
  border-radius: 999px;
}
.nav a.cta:hover { background: var(--green-deep); }

/* ---------- hero ---------- */
.hero {
  position: relative; overflow: hidden;
  min-height: 66vh; display: flex; align-items: flex-end;
  color: #fff;
}
.hero .bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  filter: saturate(1.05);
}
/* Hero and trail-card art live here rather than in an inline style, so a phone
   can be served the 800px derivative and only a wide screen pays for the
   1600px original. Paths are relative to this stylesheet, hence ../photos. */
.hero-home .bg { background-image: url("../photos/r/IMG_4553-800.jpg"); }
.hero-zoo  .bg { background-image: url("../photos/r/IMG_4542-800.jpg"); }
.hero-walls .bg { background-image: url("../photos/r/mural-joy-800.jpg"); }
.thumb-zoo   { background-image: url("../photos/r/IMG_4542-400.jpg"); }
.thumb-mon   { background-image: url("../photos/r/IMG_4532-400.jpg"); }
.thumb-walls { background-image: url("../photos/r/mural-joy-400.jpg"); }
.thumb-map   { background-image: url("../photos/r/mural-younice-400.jpg"); }
@media (min-width: 900px) {
  /* The hero is the largest thing a desktop visitor waits for, so it gets a
     1400px derivative rather than the 1600px original — about half the bytes at
     a size no one can tell apart. Each rule is stated twice on purpose: a
     browser too old for image-set() keeps the plain JPEG above it, and one that
     understands it takes the WebP. */
  .hero-home .bg { background-image: url("../photos/r/IMG_4553-1400.jpg"); }
  .hero-home .bg { background-image: image-set(
      url("../photos/r/IMG_4553-1400.webp") type("image/webp"),
      url("../photos/r/IMG_4553-1400.jpg") type("image/jpeg")); }
  .hero-zoo  .bg { background-image: url("../photos/r/IMG_4542-1400.jpg"); }
  .hero-zoo  .bg { background-image: image-set(
      url("../photos/r/IMG_4542-1400.webp") type("image/webp"),
      url("../photos/r/IMG_4542-1400.jpg") type("image/jpeg")); }
  .hero-walls .bg { background-image: url("../photos/r/mural-joy-1400.jpg"); }
  .hero-walls .bg { background-image: image-set(
      url("../photos/r/mural-joy-1400.webp") type("image/webp"),
      url("../photos/r/mural-joy-1400.jpg") type("image/jpeg")); }
  .thumb-zoo   { background-image: url("../photos/r/IMG_4542-800.jpg"); }
  .thumb-mon   { background-image: url("../photos/r/IMG_4532-800.jpg"); }
  .thumb-walls { background-image: url("../photos/r/mural-joy-800.jpg"); }
  .thumb-map   { background-image: url("../photos/r/mural-younice-800.jpg"); }
}

.hero .scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(20,16,12,.18) 0%, rgba(20,16,12,.02) 35%, rgba(20,16,12,.78) 100%);
}
.hero .inner {
  position: relative; z-index: 2; width: 100%;
  max-width: var(--maxw); margin: 0 auto; padding: 56px 20px 48px;
}
.hero .kicker { text-shadow: 0 1px 10px rgba(0,0,0,.65); }
.hero h1 { font-size: clamp(2.1rem, 6vw, 3.6rem); text-shadow: 0 2px 18px rgba(0,0,0,.45); }
.hero p.tag {
  font-size: clamp(1.05rem, 2.6vw, 1.35rem); margin-top: 10px; max-width: 640px;
  text-shadow: 0 1px 12px rgba(0,0,0,.5);
}
.hero .actions { margin-top: 24px; display: flex; gap: 14px; flex-wrap: wrap; }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 24px; border-radius: 999px; font-weight: 700;
  text-decoration: none; font-size: 1rem; border: 0; cursor: pointer;
  transition: transform .12s ease, background .12s ease;
}
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--green); color: #fff; }
.btn-primary:hover { background: var(--green-deep); }
.btn-ghost { background: rgba(255,255,255,.16); color: #fff; border: 1.5px solid rgba(255,255,255,.65); }
.btn-ghost:hover { background: rgba(255,255,255,.28); }
.btn-teal { background: var(--teal); color: #fff; }
.btn-teal:hover { background: #1f565d; }

/* ---------- sections ---------- */
section { padding: 64px 0; }
section.tight { padding: 40px 0; }
.kicker {
  font-size: .82rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--green); font-weight: 800; margin-bottom: 10px;
}
h2 { font-size: clamp(1.7rem, 4vw, 2.4rem); margin-bottom: 16px; }
.lede { font-size: 1.15rem; color: var(--ink-soft); max-width: 720px; }

/* ---------- trail cards on home ---------- */
.trail-grid { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); margin-top: 34px; }
.trail-card {
  background: var(--card); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); text-decoration: none; color: var(--ink);
  display: flex; flex-direction: column; transition: transform .15s ease, box-shadow .15s ease;
}
.trail-card:hover { transform: translateY(-4px); box-shadow: 0 8px 26px rgba(34,31,26,.16); }
.trail-card .thumb { aspect-ratio: 16/10; background-size: cover; background-position: center; }
.trail-card .body { padding: 18px 20px 22px; }
.trail-card h3 { font-size: 1.3rem; margin-bottom: 6px; }
.trail-card p { color: var(--ink-soft); font-size: .97rem; }
.trail-card .meta { margin-top: 12px; display: flex; gap: 14px; flex-wrap: wrap; font-size: .85rem; font-weight: 700; color: var(--teal); }
.badge-soon {
  display: inline-block; background: var(--gold); color: var(--ink);
  font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px; margin-bottom: 8px;
}

/* ---------- quick facts bar ---------- */
.facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 14px; margin: 26px 0 6px;
}
.fact {
  background: var(--card); border-radius: var(--radius); padding: 14px 16px;
  box-shadow: var(--shadow); text-align: center;
}
.fact .num { font-family: "Fraunces", serif; font-size: 1.45rem; font-weight: 700; color: var(--green); }
.fact .lbl { font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); font-weight: 700; }

/* ---------- map ---------- */
#map {
  height: 62vh; min-height: 380px; border-radius: var(--radius);
  box-shadow: var(--shadow); z-index: 1;
}
.map-note { font-size: .88rem; color: var(--ink-soft); margin-top: 10px; }

.locate-btn {
  position: absolute; z-index: 1000; right: 12px; top: 12px;
  background: #fff; border: 0; border-radius: 10px; padding: 10px 14px;
  font-weight: 800; font-size: .9rem; color: var(--teal); cursor: pointer;
  box-shadow: 0 1px 8px rgba(0,0,0,.25);
}
.locate-btn.active { background: var(--teal); color: #fff; }
.map-shell { position: relative; }

/* leaflet popup styling */
.leaflet-popup-content-wrapper { border-radius: 12px; }
.leaflet-popup-content { margin: 0; width: 240px !important; }
.pop { font-family: "Source Sans 3", sans-serif; }
.pop img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 12px 12px 0 0; }
.pop .pad { padding: 10px 14px 14px; }
.pop .nm { font-family: "Fraunces", serif; font-weight: 700; font-size: 1.06rem; }
.pop .sp { color: var(--green); font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.pop p { font-size: .88rem; margin-top: 6px; color: var(--ink-soft); line-height: 1.45; }
.pop a.jump { font-size: .85rem; font-weight: 700; }

/* popup photo carousel — long walls carry several views */
.popgal { position: relative; }
.popgal img { display: block; }
.popgal .pg {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: rgba(34,31,26,.55); color: #fff; font-size: 1.25rem; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.popgal .pg:hover { background: rgba(34,31,26,.8); }
.popgal .prev { left: 8px; }
.popgal .next { right: 8px; }
.popgal .pgdots {
  position: absolute; left: 0; right: 0; bottom: 7px;
  display: flex; gap: 5px; justify-content: center;
}
.popgal .pgdots i {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255,255,255,.55); box-shadow: 0 0 3px rgba(0,0,0,.4);
}
.popgal .pgdots i.on { background: #fff; }
.pop .pglabel {
  font-size: .78rem; font-style: italic; color: var(--ink-soft);
  padding: 6px 14px 0; min-height: 1.1em;
}

/* stop-card thumbnail strip */
.thumbs {
  display: flex; gap: 8px; padding: 10px 14px 0; flex-wrap: wrap;
  /* Without this the buttons stretch to the full grid-row height and the
     selected one's border draws a tall box around a small thumbnail. */
  align-items: flex-start;
}
.thumbs button {
  border: 2.5px solid transparent; border-radius: 9px; padding: 0;
  background: none; cursor: pointer; line-height: 0;
  transition: border-color .15s, transform .15s;
}
.thumbs button img {
  width: 74px; height: 52px; object-fit: cover; border-radius: 7px;
}
.thumbs button:hover { transform: translateY(-2px); }
.thumbs button.on { border-color: var(--green); }
.thumb-label {
  font-size: .82rem; font-style: italic; color: var(--ink-soft);
  padding: 6px 14px 0; min-height: 1.2em;
}

.stop-pin {
  background: var(--green); color: #fff; border-radius: 50%;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: .85rem; border: 2.5px solid #fff;
  box-shadow: 0 1px 6px rgba(0,0,0,.4); font-family: "Source Sans 3", sans-serif;
}
.stop-pin.landmark { background: var(--teal); }
/* murals page — pin colour tells you which route a stop belongs to */
.stop-pin.g-downtown   { background: var(--green); }
.stop-pin.g-franklin   { background: var(--green-deep); }
.stop-pin.g-silo       { background: var(--teal); }
.stop-pin.g-washington { background: var(--gold); color: var(--ink); }
.stop-pin.g-eastwaco   { background: var(--plum); }
.stop-pin.g-drive      { background: #5c554b; }
/* what-is-it badge: MURAL · STATUE · FOUNTAIN · MONUMENT · STENCIL · SIGN · SCULPTURE */
.kind {
  display: inline-block; margin-left: 8px; padding: 2px 9px;
  border-radius: 999px; font-size: .68rem; font-weight: 800;
  letter-spacing: .09em; vertical-align: 1px;
  background: var(--ivory-deep, #f1eadd); color: var(--ink-soft, #5c554b);
  border: 1px solid var(--line, #e5dccd);
}

/* route legend under the map */
.legend { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px; font-size: .88rem; font-weight: 700; color: var(--ink-soft); }
.legend span { display: inline-flex; align-items: center; gap: 7px; }
.legend i { width: 15px; height: 15px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.3); }
.legend i.dt { background: var(--green); }
.legend i.fr { background: var(--green-deep); }
.legend i.si { background: var(--teal); }
.legend i.wa { background: var(--gold); }
.legend i.dr { background: #5c554b; }
.legend .mode-note { font-style: italic; font-weight: 600; opacity: .8; }

/* route intro band between groups of stop cards */
.route-head { margin: 40px 0 4px; }
.route-head:first-child { margin-top: 8px; }
.route-head h3 {
  font-family: "Fraunces", serif; font-size: 1.55rem; font-weight: 700;
  display: flex; align-items: center; gap: 11px; margin-bottom: 6px;
}
.route-head h3 i { width: 17px; height: 17px; border-radius: 50%; flex: none; }
.route-head p { color: var(--ink-soft); max-width: 700px; }
.route-head .rmeta {
  margin-top: 8px; font-size: .85rem; font-weight: 800; color: var(--teal);
  letter-spacing: .04em; text-transform: uppercase;
}

.me-dot {
  width: 18px; height: 18px; border-radius: 50%;
  background: #2b7de0; border: 3px solid #fff;
  box-shadow: 0 0 0 6px rgba(43,125,224,.25);
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 4px rgba(43,125,224,.30); }
  60% { box-shadow: 0 0 0 12px rgba(43,125,224,.05); }
  100% { box-shadow: 0 0 0 4px rgba(43,125,224,.30); }
}

/* ---------- how to enjoy ---------- */
.modes { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 26px; }
.mode {
  background: var(--card); border-radius: var(--radius); padding: 22px;
  box-shadow: var(--shadow);
}
.mode .ico { font-size: 1.9rem; }
.mode h3 { margin: 8px 0 6px; font-size: 1.15rem; }
.mode p { font-size: .95rem; color: var(--ink-soft); }

/* ---------- stops list ---------- */
.stops { display: grid; gap: 26px; margin-top: 34px; }
.stop-card {
  background: var(--card); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); display: grid; grid-template-columns: 340px 1fr;
}
/* The cover is a <picture> rather than a background-image, because a
   background-image cannot be lazy-loaded — see js/photo.js. The box lives on
   the container so the image can fill it without knowing its own proportions
   (these photos are a mix of landscape and portrait). */
.stop-card .photo {
  display: block; position: relative; min-height: 240px;
  background: var(--ivory-deep);
}
.stop-card .photo img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.stop-card .body { padding: 22px 26px 24px; }
.stop-card .n {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--green); color: #fff; width: 30px; height: 30px;
  border-radius: 50%; font-weight: 800; font-size: .9rem; margin-right: 10px; flex: none;
}
.stop-card .n.landmark { background: var(--teal); }
/* murals page — badge colour matches the route's map pins */
.stop-card .n.n-downtown   { background: var(--green); }
.stop-card .n.n-franklin   { background: var(--green-deep); }
.stop-card .n.n-silo       { background: var(--teal); }
.stop-card .n.n-washington { background: var(--gold); color: var(--ink); }
.stop-card .n.n-eastwaco   { background: var(--plum); }
.stop-card .n.n-drive      { background: #5c554b; }
.stop-card h3 { font-size: 1.45rem; display: flex; align-items: center; }
/* the stop's name links to its own page */
.stop-card h3 .stop-title { color: inherit; text-decoration: none; }
.stop-card h3 .stop-title:hover { color: var(--green); text-decoration: underline; }
.stop-card .species {
  color: var(--green); font-size: .82rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em; margin: 4px 0 10px;
}
.stop-card p.story { color: var(--ink-soft); }
.stop-card .row { margin-top: 14px; display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }
.stop-card .row a { font-size: .9rem; font-weight: 700; }
@media (max-width: 760px) {
  .stop-card { grid-template-columns: 1fr; }
  .stop-card .photo { aspect-ratio: 4/3; min-height: 0; }
}

/* ---------- per-artwork stop page (/zoo/*.html, /walls/*.html) ----------
   One page per artwork, so a search for the piece by its real name has
   somewhere to land and a shared link carries that piece's own photo. */
.stop-page { padding: 26px 0 64px; }

.crumb {
  font-size: .86rem; color: var(--ink-soft); margin-bottom: 18px;
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
}
.crumb a { font-weight: 600; text-decoration: none; }
.crumb a:hover { text-decoration: underline; }
.crumb span { opacity: .5; }
.crumb em { font-style: normal; color: var(--ink); font-weight: 700; }

.stop-hero {
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
  background: var(--ivory-deep);
}
/* ☠️ height:auto is load-bearing. These <img>s carry width/height attributes so
   the browser can reserve the right box before the photo arrives, but those
   attributes act as presentational hints — with BOTH dimensions set,
   aspect-ratio is ignored and the image renders at its literal pixel height.
   One of the two has to be auto for the ratio to win. */
.stop-hero img { width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; }
@media (min-width: 700px) { .stop-hero img { aspect-ratio: 16/9; } }

.stop-head { margin-top: 26px; }
.stop-head h1 {
  font-size: clamp(1.9rem, 4.6vw, 2.9rem);
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.stop-head h1 .n {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--green); color: #fff; width: 44px; height: 44px;
  border-radius: 50%; font-family: "Source Sans 3", sans-serif;
  font-weight: 800; font-size: 1.15rem; flex: none;
}
.stop-head h1 .n.n-downtown   { background: var(--green); }
.stop-head h1 .n.n-franklin   { background: var(--green-deep); }
.stop-head h1 .n.n-silo       { background: var(--teal); }
.stop-head h1 .n.n-washington { background: var(--gold); color: var(--ink); }
.stop-head h1 .n.n-eastwaco   { background: var(--plum); }
.stop-head h1 .n.n-drive      { background: #5c554b; }
.stop-head .official {
  margin-top: 12px; color: var(--ink-soft); font-size: .95rem; font-weight: 600;
}
.stop-head .lede { margin-top: 14px; font-size: 1.2rem; }

.stop-body { margin-top: 24px; max-width: 720px; }
.stop-body p { color: var(--ink-soft); margin-bottom: 16px; font-size: 1.06rem; }

.look {
  background: var(--card); border-left: 5px solid var(--gold);
  border-radius: 10px; padding: 18px 22px; box-shadow: var(--shadow);
  color: var(--ink-soft); font-size: 1.02rem; margin-top: 22px;
}
.look strong {
  display: block; color: var(--green); font-size: .8rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; margin-bottom: 6px;
}

.stop-actions { margin-top: 30px; display: flex; gap: 14px; flex-wrap: wrap; }

/* extra views of a long wall */
.stop-gal { margin-top: 44px; }
.stop-gal h2 { font-size: 1.5rem; }
.gal-grid {
  display: grid; gap: 16px; margin-top: 18px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.gal-item {
  background: var(--card); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow);
}
.gal-item img { width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; }
.gal-item figcaption {
  padding: 9px 13px 12px; font-size: .84rem; font-style: italic; color: var(--ink-soft);
}

/* keep them walking */
.pager {
  margin-top: 44px; display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.pager a {
  background: var(--card); border-radius: var(--radius); padding: 16px 20px;
  box-shadow: var(--shadow); text-decoration: none; color: var(--ink);
  transition: transform .15s ease, box-shadow .15s ease;
}
.pager a:hover { transform: translateY(-3px); box-shadow: 0 8px 26px rgba(34,31,26,.16); }
.pager .dir {
  display: block; font-size: .76rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--green); margin-bottom: 4px;
}
.pager .nm { font-family: "Fraunces", serif; font-weight: 600; font-size: 1.1rem; }
.pager .pager-next { text-align: right; }
/* holds the empty cell at the first and last stop of a trail */
.pager .pager-gap { display: none; }
@media (min-width: 620px) { .pager .pager-gap { display: block; } }

.stop-sponsor {
  margin-top: 48px; background: var(--ink); color: #f4efe6;
  border-radius: var(--radius); padding: 36px 32px;
}
.stop-sponsor h2 { color: #fff; font-size: 1.55rem; }
.stop-sponsor p { color: #cfc6b8; max-width: 640px; margin-top: 10px; }
.stop-sponsor .btn { margin-top: 20px; }

/* ---------- sponsor ---------- */
.sponsor {
  background: var(--ink); color: #f4efe6; border-radius: var(--radius);
  padding: 44px 36px; margin: 20px 0;
}
.sponsor h2 { color: #fff; }
.sponsor p { color: #cfc6b8; max-width: 680px; }
.sponsor .btn { margin-top: 20px; }

/* ---------- footer ---------- */
footer {
  border-top: 1px solid rgba(34,31,26,.1); padding: 36px 0 48px;
  color: var(--ink-soft); font-size: .92rem;
}
footer .cols { display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
footer .logo { font-size: 1.1rem; }

/* small screens */
@media (max-width: 560px) {
  .nav a:not(.cta) { display: none; }
  section { padding: 46px 0; }
  #map { height: 68vh; }
}

/* ---------- blog (v5) ---------- */
.nav a.on { color: var(--green); }

.blog-head { padding: 52px 0 8px; }
.blog-head h1 { font-size: clamp(2rem, 5vw, 3rem); }
.blog-head .lede { margin-top: 12px; }

.blog-grid {
  display: grid; gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  margin-top: 34px;
}
.blog-card {
  background: var(--card); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); text-decoration: none; color: var(--ink);
  display: flex; flex-direction: column;
  transition: transform .15s ease, box-shadow .15s ease;
}
.blog-card:hover { transform: translateY(-4px); box-shadow: 0 8px 26px rgba(34,31,26,.16); }
.blog-card .thumb-img { aspect-ratio: 16/10; overflow: hidden; }
.blog-card .thumb-img img { width: 100%; height: 100%; object-fit: cover; }
.blog-card .body { padding: 18px 20px 22px; }
.blog-card h2, .blog-card h3 { font-size: 1.25rem; margin: 8px 0 6px; }
.blog-card p { color: var(--ink-soft); font-size: .97rem; }
.blog-card .meta {
  margin-top: 12px; display: flex; gap: 14px; flex-wrap: wrap;
  font-size: .85rem; font-weight: 700; color: var(--teal);
}
.cat-badge {
  display: inline-block; background: var(--ivory-deep); color: var(--green-deep);
  font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px;
}

.post-meta { margin-top: 8px; font-size: .9rem; font-weight: 700; color: var(--teal); }
.post-body { font-size: 1.06rem; }
.post-body h2 { font-size: 1.55rem; margin: 36px 0 12px; }
.post-body h3 { font-size: 1.2rem; margin: 28px 0 10px; }
.post-body blockquote {
  border-left: 5px solid var(--teal); background: var(--card);
  border-radius: 10px; box-shadow: var(--shadow);
  padding: 16px 22px; margin: 22px 0; color: var(--ink-soft); font-style: italic;
}
.post-figure {
  margin: 26px 0; background: var(--card); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
}
.post-figure img { width: 100%; height: auto; }
.post-figure figcaption {
  padding: 9px 14px 12px; font-size: .84rem; font-style: italic; color: var(--ink-soft);
}
.post-cta .cta-row { margin-top: 20px; display: flex; gap: 14px; flex-wrap: wrap; }
.post-cta .btn { margin-top: 0; }

/* homepage "from the blog" strip shares the card styles above */
.home-blog .blog-grid { margin-top: 26px; }
.home-blog .more-link { margin-top: 22px; font-weight: 700; }

/* ---------- trail-page FAQ (v5) ---------- */
.faq { margin-top: 40px; }
.faq h2 { font-size: 1.6rem; }
.faq details {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  margin-top: 12px; padding: 0 20px;
}
.faq summary {
  cursor: pointer; font-weight: 700; padding: 15px 0;
  font-size: 1.02rem; list-style: none; position: relative; padding-right: 30px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  color: var(--green); font-weight: 800; font-size: 1.3rem;
}
.faq details[open] summary::after { content: "–"; }
.faq details p { color: var(--ink-soft); padding-bottom: 16px; }

/* ══════════════════════════════════════════════════════════════════════════
   THE ART WACO SCAVENGER HUNT  (v6)                              hunt.html
   ══════════════════════════════════════════════════════════════════════════

   ☠️ EVERY RULE BELOW IS SCOPED TO #hunt-app, a .hunt-* class, or
   body.hunt-page. NOT ONE EXISTING SELECTOR IS MODIFIED OR RE-DECLARED.

   That constraint is not stylistic, it is what makes shipping this safe: this
   one stylesheet is served to sixty pages, only four of which get the ?v=6
   bump. Everything above this banner is byte-identical to v5, so the 58
   generated stop pages and the whole blog can serve a cached v5 forever and
   nothing can regress. v6 is a strict superset of v5.

   Two consequences worth spelling out, because they look like mistakes:
     • `body { padding-bottom: 104px }` would have been the obvious way to
       clear the fixed bottom bar. It is written as `body.hunt-page` instead,
       because on a shared stylesheet the plain form would put 104px of dead
       space at the foot of every page on the site.
     • The @media print block is scoped `body.hunt-page …` for the same reason.
       Printing murals.html must not suddenly lose its header.

   Mobile first. The 375px phone standing in a park is the primary device;
   desktop is the second thought, not the first.
   ══════════════════════════════════════════════════════════════════════════ */

body.hunt-page { padding-bottom: 108px; }
body.hunt-page.hunt-locked { overflow: hidden; }

/* ☠️ NOT GOLD. `--gold` #d9a441 is 2.09:1 against `--ivory` and 2.25:1 against
   `--card` — below the 3:1 floor WCAG 2.2 SC 1.4.11 sets for a focus
   indicator — and `outline-offset` puts the ring on the page ground, so those
   are the ratios that govern everywhere on this page. It is also the only
   focus indicator here: it replaces the UA's own ring on every tab stop in the
   app, and pressing Space on a square MARKS it, so "which square am I on" has
   to be answerable before the key goes down. `--green-deep` is 8.46:1 on
   ivory and 6.30:1 on white, and it is still the house palette. */
#hunt-app :focus-visible,
.hunt-memorial a:focus-visible { outline: 3px solid var(--green-deep); outline-offset: 2px; }

/* ☠️ HOUSE RULE 3. An author `display` beats the UA's [hidden]{display:none},
   so every element below that sets a display value needs this stated once,
   loudly, or a "hidden" panel sits there in the middle of the page. */
.hunt-panel[hidden], .hunt-banner[hidden], .hunt-toast[hidden], .hunt-finish[hidden],
.hunt-month[hidden], .hunt-resume[hidden], .hunt-drift[hidden], .hunt-err[hidden],
.hunt-carnote[hidden], .hunt-rest[hidden], .hunt-momentnote[hidden],
.bar-gps[hidden], .hunt-cell.is-blank { display: none !important; }

.hunt-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- page top ----------
   ☠️ EVERY PIXEL HERE COMES OFF THE TOP OF THE CARD. SPEC §6.10 and the PART 13
   acceptance list require the card above the fold with no `?c=`; this block is
   the only thing between the sticky header and it, and the first build spent
   ~680px of a 667px phone on it. Budgeted, at 375px: 14 pad + ~32 kicker + ~63
   h1 + ~59 lede + ~76 facts ≈ 244px, which puts the grid around 545px — a full
   row of photographs above the fold on the smallest phone in use and three
   rows on a modern one. Do not restore the second lede or loosen the padding
   without re-measuring on a 375×667 viewport. */
.hunt-top { padding: 14px 0 2px; }
.hunt-top h1 { font-size: clamp(1.7rem, 5.6vw, 3.1rem); margin-bottom: 8px; }
.hunt-top .lede { margin-bottom: 0; }
/* Four facts across even at 375px, rather than a 2×2 grid of tall cards. */
.hunt-facts { grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 14px 0 0; }
.hunt-facts .fact { padding: 8px 6px; }
.hunt-facts .num { font-size: 1rem; line-height: 1.25; letter-spacing: .02em; }
.hunt-facts .lbl { font-size: .6rem; line-height: 1.25; }
@media (min-width: 620px) {
  .hunt-facts { gap: 14px; margin-top: 20px; }
  .hunt-facts .fact { padding: 14px 16px; }
  .hunt-facts .num { font-size: 1.15rem; letter-spacing: .04em; }
  .hunt-facts .lbl { font-size: .8rem; }
}
/* ☠️ `section.tight` is (0,1,1) and `.hunt-section` was (0,1,0), so the old
   rule never applied at all and this section really carried 40px of padding.
   Stated at (0,2,1) so it wins, and cut to 12 for the same reason as above. */
section.tight.hunt-section { padding-top: 12px; }

/* ---------- chooser (below the card — see the note in hunt.js mount) ------- */
.hunt-chooser { margin: 22px 0 4px; padding-top: 16px; border-top: 1px solid rgba(34,31,26,.1); }
.hunt-choosehead { font-size: .9rem; font-weight: 700; color: var(--ink-soft); margin-bottom: 10px; }
.hunt-codestrip { margin-top: 14px; }
.hunt-chiprow { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; align-items: center; }
.hunt-chip {
  font: inherit; font-weight: 700; font-size: .9rem;
  padding: 9px 15px; min-height: 42px; border-radius: 999px; cursor: pointer;
  background: var(--card); color: var(--ink-soft);
  border: 1.5px solid rgba(34,31,26,.14);
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.hunt-chip:hover:not([disabled]) { border-color: var(--green); color: var(--green); }
.hunt-chip.is-on { background: var(--green); border-color: var(--green); color: #fff; }
.hunt-chip[disabled] { opacity: .38; cursor: not-allowed; }
.hunt-chipnote { font-size: .82rem; color: var(--ink-soft); font-style: italic; }

.hunt-join { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.hunt-join label { font-weight: 700; font-size: .9rem; color: var(--ink-soft); }
.hunt-code-in {
  font: inherit; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  width: 8.5em; padding: 9px 12px; min-height: 42px;
  border: 1.5px solid rgba(34,31,26,.18); border-radius: 10px;
  background: var(--card); color: var(--ink);
}
.hunt-joinbtn {
  font: inherit; font-weight: 800; font-size: .9rem; cursor: pointer;
  padding: 9px 18px; min-height: 42px; border: 0; border-radius: 999px;
  background: var(--teal); color: #fff;
}
.hunt-hint, .hunt-err { flex-basis: 100%; font-size: .8rem; color: var(--ink-soft); margin-top: 2px; }
.hunt-err { color: var(--green-deep); font-weight: 700; }

/* ---------- card of the month ---------- */
.hunt-month {
  display: block; background: var(--gold); color: var(--ink);
  border-radius: var(--radius); padding: 14px 18px; margin-bottom: 16px;
  font-size: .95rem; line-height: 1.5;
}
.hunt-month a { color: var(--ink); font-weight: 800; }

/* ---------- card head ---------- */
.hunt-resume {
  display: block; background: var(--ivory-deep); border-radius: 10px;
  padding: 10px 14px; font-size: .9rem; margin-bottom: 12px; color: var(--ink-soft);
}
.hunt-fresh {
  font: inherit; font-weight: 800; font-size: .88rem; cursor: pointer;
  background: none; border: 0; padding: 0; color: var(--teal); text-decoration: underline;
}
.hunt-cardhead { margin-bottom: 12px; }
.hunt-name { font-size: clamp(1.5rem, 5.2vw, 2.1rem); margin-bottom: 2px; }
.hunt-code {
  font-weight: 800; letter-spacing: .22em; font-size: 1.02rem;
  color: var(--green); margin-bottom: 6px;
}
/* Three or four lines of summary above the grid on a phone is a screenful of
   its own; the wording is unchanged, it is just set tighter down there. */
.hunt-summary { color: var(--ink-soft); font-size: .98rem; font-weight: 600; }
@media (max-width: 480px) { .hunt-summary { font-size: .9rem; line-height: 1.4; } }
.hunt-carnote, .hunt-drift {
  display: block; font-size: .86rem; color: var(--ink-soft);
  font-style: italic; margin-top: 6px;
}
.hunt-headrow { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.hunt-deal, .hunt-copy, .hunt-text {
  font: inherit; font-weight: 700; font-size: .88rem; cursor: pointer;
  padding: 9px 16px; min-height: 42px; border-radius: 999px;
  border: 1.5px solid rgba(34,31,26,.16); background: var(--card); color: var(--ink);
}
.hunt-deal { background: var(--ink); color: #fff; border-color: var(--ink); }
.hunt-deal:hover { background: var(--green); border-color: var(--green); }
.hunt-codenote { font-size: .82rem; color: var(--ink-soft); margin-top: 8px; }
.hunt-nostore {
  background: var(--ivory-deep); border-left: 4px solid var(--gold);
  border-radius: 8px; padding: 10px 14px; font-size: .88rem; margin-top: 12px;
}

/* ---------- the card ---------- */
.hunt-grid {
  display: grid; grid-template-columns: repeat(var(--n, 3), 1fr);
  gap: 8px; list-style: none; margin: 0; padding: 0;
}
@media (max-width: 420px) { .hunt-grid { gap: 6px; } }

.hunt-cell { position: relative; }

.hunt-sq {
  display: block; width: 100%; padding: 0; border: 0; cursor: pointer;
  background: var(--card); border-radius: 10px; overflow: hidden;
  box-shadow: var(--shadow); position: relative; text-align: left;
  /* kills the 300 ms double-tap-to-zoom delay, which on a bingo card reads as
     "the app is slow" */
  touch-action: manipulation;
  transition: transform .12s ease, box-shadow .12s ease;
}
.hunt-sq:active { transform: scale(.97); }

/* ☠️ HOUSE RULE 1. The box lives on the CONTAINER; the <img> carries no width
   or height attribute at all. With both dimensions set, aspect-ratio is
   silently ignored and the photo renders at its literal pixel height. Same
   proven pattern as .stop-card .photo. */
.hunt-sq .sq-shot {
  display: block; position: relative; aspect-ratio: 1; background: var(--ivory-deep);
}
.hunt-sq .sq-shot img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: opacity .3s ease;
}

.sq-n {
  position: absolute; top: 5px; left: 5px; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 5px; border-radius: 999px;
  background: var(--green); color: #fff;
  font-size: .72rem; font-weight: 800; line-height: 1;
  border: 1.5px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.sq-n.landmark     { background: var(--teal); }
.sq-n.n-downtown   { background: var(--green); }
.sq-n.n-franklin   { background: var(--green-deep); }
.sq-n.n-silo       { background: var(--teal); }
.sq-n.n-washington { background: var(--gold); color: var(--ink); }
.sq-n.n-eastwaco   { background: var(--plum); }
.sq-n.n-drive      { background: #5c554b; }

.sq-car {
  position: absolute; top: 5px; right: 5px; z-index: 3; font-size: .78rem;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.5));
}

.sq-name {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 5px 7px 6px; font-size: 13px; font-weight: 700; line-height: 1.2;
  color: var(--ink); background: rgba(250,246,239,.93);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.sq-name i { font-style: normal; font-weight: 600; color: var(--ink-soft); }
/* At 62 px a name band is unreadable and would cover the photograph, so the
   5×5 drops it — which is precisely why tapping a tile opens a panel. It stays
   in the DOM for the screen reader and for the printed card. */
.hunt-grid[style*="--n:5"] .sq-name { display: none; }
.sq-sub, .sq-dare, .sq-tick { display: none; }

/* ---------- the stamp ---------- */
.sq-stamp {
  position: absolute; z-index: 4; top: 50%; left: 50%;
  width: 62%; aspect-ratio: 1; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: "Fraunces", Georgia, serif; font-weight: 700;
  font-size: clamp(.85rem, 4.2vw, 1.5rem);
  color: var(--green-deep);
  border: 3px solid var(--green-deep);
  /* the soft edge is what makes it read as ink rather than as UI */
  background: radial-gradient(circle at 42% 38%,
              rgba(192,90,53,.30) 0%, rgba(192,90,53,.16) 58%, rgba(192,90,53,.05) 100%);
  opacity: 0; visibility: hidden;
  transform: translate(-50%, -50%) rotate(var(--ang, 0deg)) scale(2.2);
}
.hunt-cell.is-found .sq-stamp {
  opacity: .92; visibility: visible;
  transform: translate(-50%, -50%) rotate(var(--ang, 0deg)) scale(1);
  transition: transform .26s cubic-bezier(.2, 1.4, .4, 1), opacity .09s ease;
}

/* ☠️ THE INVERSION, v2 (David, 8/21/26). A found square used to go quiet so
   the card showed WHAT IS LEFT. Now a found square turns over its piece of ONE
   kid-friendly artwork — the Baylor Flowers "You were MADE to Bloom" wall — so
   a finished card is a single picture, not N photographs. WHAT IS LEFT is
   still the first thing the card says: the squares that are still photographs
   are the holes in the picture. The dimming below stays as the graceful
   fallback for the day the reveal image fails to load: a found square must
   never look unfound. ☠️ Keep this background-image URL in step with
   REVEAL_SRC in js/hunt.js (the share PNG draws the same artwork). */
.hunt-cell.is-found .sq-shot img { opacity: .32; }
.hunt-cell.is-found .sq-shot     { background: var(--ivory-deep); }
.hunt-cell.is-found .sq-name     { background: rgba(241,234,222,.9); color: var(--ink-soft); }
.hunt-cell.is-found .hunt-sq     { box-shadow: none; }

/* ---------- the reveal ---------- */
/* ☠️ The picture is now the found-signal, so the two things that used to mark a
   found square must get OUT OF ITS WAY — and the one thing that says WHICH
   square this is must stay ON TOP of it. Shipped 8/21 without this and David
   caught it immediately: every found tile lost its number and wore a giant ink
   circle, so a filled card read as "the same photo in every slot".
     · .sq-n / .sq-car go above the reveal (they were z-index 3, same as the
       reveal, and lost on DOM order — the number vanished under the picture).
     · the big centre stamp is suppressed ON SCREEN only; print has no reveal
       (see the @media print rule below) and still needs its stamp. */
.sq-n, .sq-car { z-index: 6; }
@media screen { .hunt-cell.is-found .sq-stamp { display: none; } }

/* The quiet replacement for the stamp: a small inked check in the corner. The
   element already exists in the markup and repaintCell() already toggles
   .is-inked on it — this only gives it a face. */
.hunt-cell.is-found .sq-tick.is-inked,
.hunt-cell.is-free  .sq-tick.is-inked {
  display: flex; align-items: center; justify-content: center;
  position: absolute; z-index: 6; right: 5px; bottom: 5px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--green); border: 1.5px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.hunt-cell.is-found .sq-tick.is-inked::after,
.hunt-cell.is-free  .sq-tick.is-inked::after {
  content: ""; width: 9px; height: 5px; margin-top: -3px;
  border-left: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
  transform: rotate(-45deg);
}

.sq-reveal {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background-image: url(../photos/hunt-reveal.jpg?v=2);
  background-repeat: no-repeat;
  /* --rs/--rx/--ry are precomputed per cell in hunt.js cellHtml — no calc()
     division on a var(), which the oldest Safaris this page serves mistrust. */
  background-size: var(--rs, 300%) var(--rs, 300%);
  background-position: var(--rx, 0%) var(--ry, 0%);
  border-radius: inherit;
  opacity: 0; transform: scale(1.12);
  transition: transform .3s cubic-bezier(.2, 1.2, .4, 1), opacity .22s ease;
}
.hunt-cell.is-found .sq-reveal { opacity: 1; transform: scale(1); }
/* The free square's piece is placed from the start — a puzzle the city has
   already started for you. */
.hunt-cell.is-free .sq-free { position: relative; overflow: hidden; }
.hunt-cell.is-free .sq-reveal { opacity: 1; transform: scale(1); }
/* Paper cards stay paper: squares print as clean frames to tick by hand. */
@media print { .sq-reveal { display: none !important; } }

/* ---------- free + moment squares ---------- */
.hunt-cell.is-free .sq-free {
  aspect-ratio: 1; border-radius: 10px; background: var(--gold); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 4px; box-shadow: var(--shadow);
}
.hunt-cell.is-free .sq-free span {
  font-family: "Fraunces", Georgia, serif; font-weight: 700;
  font-size: clamp(.9rem, 4.4vw, 1.5rem); line-height: 1;
}
.hunt-cell.is-free .sq-free small { font-size: .58rem; font-weight: 700; letter-spacing: .06em; opacity: .72; }

/* ☠️ BUDGETED AGAINST 52px, NOT AGAINST `overflow: hidden`. A Moment square
   only ever appears on a 5×5, where a tile at 375px is (335 − 4×6)/5 = 62.2px
   — about 52px of content box. The base `.hunt-sq` sets `overflow: hidden`,
   which makes this button a scroll container, which in turn switches OFF the
   automatic-minimum-size rule: the box CANNOT grow to fit and anything over
   budget is silently sliced, top and bottom, by `justify-content: center`.
   The first build stacked star 17.6 + text 40.7 + tag 14.1 + margins = 78px
   into 50px, which cut the star in half and clipped the word MOMENT away
   entirely — leaving colour as the only thing distinguishing a Moment from the
   free square, against SPEC §7.11 ("carry visible words, not just gold").
   So: the star comes OUT of the flow (it is decoration, aria-hidden), and what
   is left is the instruction and the label, which are the two things that mean
   something. 3 lines × 11.5 × 1.12 = 38.6 + 2 + 8.8 = 49.4 ≤ 52. Below 360px
   the tile drops to ~43px of content and the clamp drops with it. */
.hunt-cell.is-moment .hunt-sq {
  aspect-ratio: 1; background: var(--gold); color: var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 5px 4px;
}
.sq-star {
  position: absolute; top: 3px; left: 4px; z-index: 2;
  font-size: .8rem; line-height: 1; opacity: .5;
}
.sq-moment {
  font-size: 11.5px; font-weight: 700; line-height: 1.12;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 360px) { .sq-moment { -webkit-line-clamp: 2; } }
/* opacity .7 computed to 3.96:1 on gold — under AA. .85 is 5.5:1 and still
   reads as a quiet label. */
.sq-tag {
  font-size: .55rem; font-weight: 800; letter-spacing: .12em;
  opacity: .85; margin-top: 2px; line-height: 1;
}
.hunt-cell.is-moment.is-found .hunt-sq { background: var(--ivory-deep); color: var(--ink-soft); }
.hunt-cell.is-moment .sq-stamp { border-color: var(--ink); color: var(--ink); background: none; }

/* ---------- the ⓘ corner ---------- */
/* An anchor, not a button, because buttons cannot nest and the tile IS one big
   button. It jumps to this square's Roll Call row. */
.sq-more {
  position: absolute; right: 0; bottom: 0; z-index: 5;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  font-size: 1rem; text-decoration: none; color: var(--ink-soft);
  background: rgba(250,246,239,.86); border-radius: 10px 0 10px 0;
}
.sq-more:hover { color: var(--green); background: #fff; }
.hunt-grid[style*="--n:5"] .sq-more { width: 24px; height: 24px; font-size: .82rem; }

/* completion bloom — reading order, 30 ms apart */
.hunt-grid.is-bloom { outline: 2px solid var(--gold); outline-offset: 6px; border-radius: 6px; }
.hunt-grid.is-bloom .hunt-cell.is-found .sq-shot img {
  opacity: 1; transition: opacity .5s ease calc(var(--i, 0) * 30ms);
}

@media (prefers-reduced-motion: reduce) {
  .hunt-cell.is-found .sq-stamp {
    transform: translate(-50%, -50%) rotate(var(--ang, 0deg)) scale(1);
    transition: opacity .12s linear !important;
  }
  .hunt-sq, .hunt-cell, .hunt-grid.is-bloom .hunt-cell.is-found .sq-shot img {
    transition: none !important;
  }
  .hunt-sq:active { transform: none; }
}

/* ---------- notes under the card ---------- */
.hunt-momentnote {
  display: block; background: var(--card); border-left: 5px solid var(--gold);
  border-radius: 10px; padding: 12px 16px; margin-top: 14px;
  font-size: .92rem; color: var(--ink-soft); box-shadow: var(--shadow);
}
/* Says out loud what the tiles are doing. Without this the reveal is a magic
   trick nobody explained: you tap a wall in Waco and a piece of an unrelated
   flower mural appears. One sentence turns that into the point of the game. */
.hunt-revealnote {
  display: block; background: var(--card); border-left: 5px solid var(--green);
  border-radius: 10px; padding: 12px 16px; margin-top: 14px;
  font-size: .92rem; color: var(--ink-soft); box-shadow: var(--shadow);
}
.hunt-revealnote a { color: var(--green-deep); }
/* The card's name is a NAME, not a subject — "The Kindly Elephant" is a card,
   not a card about an elephant. The kicker above it says so at a glance. */
.hunt-cardhead .kicker { margin-bottom: 2px; }
.hunt-privacy { font-size: .86rem; color: var(--ink-soft); margin-top: 20px; max-width: 720px; }
/* NB: no `display` here on purpose — see the note in hunt.html. This class is
   on a <div> INSIDE the <noscript>, so it is already block-level, and nothing
   here can leak past the UA rule that hides <noscript> when JS is on. */
.hunt-noscript {
  background: var(--card); border-radius: var(--radius);
  padding: 20px 22px; box-shadow: var(--shadow); margin-top: 16px;
}
.hunt-noscript h2 { font-size: 1.3rem; margin-bottom: 8px; }
.hunt-sorry { background: var(--card); border-radius: var(--radius); padding: 26px 24px; box-shadow: var(--shadow); }
.hunt-sorry h2 { font-size: 1.4rem; margin-bottom: 8px; }

.hunt-printbox {
  margin-top: 26px; background: var(--ivory-deep); border-radius: var(--radius);
  padding: 18px 20px;
}
.hunt-printbox p { font-size: .92rem; color: var(--ink-soft); margin-bottom: 12px; }

/* ---------- the Roll Call ---------- */
.hunt-roll { margin-top: 30px; }
.roll-head { font-size: 1.35rem; margin-bottom: 12px; }
.roll-row {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--card); border-radius: 12px; box-shadow: var(--shadow);
  padding: 12px 14px; margin-bottom: 10px;
  scroll-margin-top: 76px;      /* the sticky header must not eat the anchor */
}
.roll-row.is-found { background: var(--ivory-deep); box-shadow: none; }
.roll-thumb { flex: none; width: 72px; }
.roll-thumb img { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; }
.roll-row.is-found .roll-thumb img { opacity: .45; }
.roll-text { min-width: 0; flex: 1; }
.roll-n { font-size: .72rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--green); }
.roll-text h3 { font-size: 1.08rem; margin: 2px 0 4px; }
.roll-text h3 a { color: inherit; text-decoration: none; }
.roll-text h3 a:hover { color: var(--green); text-decoration: underline; }
.roll-official { font-size: .84rem; color: var(--ink-soft); font-weight: 600; }
.roll-species { font-size: .74rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--green); margin-top: 3px; }
.roll-look { font-size: .9rem; color: var(--ink-soft); margin-top: 7px; }
.roll-look strong {
  display: block; color: var(--green); font-size: .7rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; margin-bottom: 2px;
}
.roll-links { margin-top: 10px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; font-size: .86rem; font-weight: 700; }
.roll-check { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; min-height: 44px; }
.roll-check input { width: 22px; height: 22px; accent-color: var(--green); }

/* ---------- the reveal panel ---------- */
.hunt-panel {
  display: flex; flex-direction: column;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1500;
  max-height: 86vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--ivory); border-radius: 18px 18px 0 0;
  box-shadow: 0 -6px 34px rgba(34,31,26,.28);
  animation: hunt-rise .26s ease;
  padding-bottom: env(safe-area-inset-bottom);
}
@keyframes hunt-rise { from { transform: translateY(14%); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .hunt-panel { animation: none; } }
@media (min-width: 700px) {
  .hunt-panel { left: 50%; right: auto; transform: translateX(-50%); width: 560px; border-radius: 18px 18px 0 0; }
}
.panel-shot { position: relative; aspect-ratio: 4/3; background: var(--ivory-deep); }
.panel-shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.panel-body { padding: 18px 20px 24px; }
.panel-kicker { font-size: .74rem; font-weight: 800; letter-spacing: .14em; color: var(--green); }
.panel-name { font-size: 1.5rem; margin: 4px 0 2px; }
.panel-species { font-size: .78rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--green); }
.panel-official { font-size: .9rem; color: var(--ink-soft); margin-top: 6px; }
.panel-look { margin-top: 16px; }
.panel-gpsbadge {
  margin-top: 12px; font-size: .84rem; font-weight: 700; color: var(--teal);
}
.panel-actions { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
.panel-actions .btn { font-size: .92rem; padding: 11px 18px; }
.panel-undo {
  font: inherit; font-weight: 700; cursor: pointer; margin-top: 14px;
  display: block; width: 100%; min-height: 46px; border-radius: 999px;
  background: none; border: 1.5px solid rgba(34,31,26,.2); color: var(--ink-soft);
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.panel-undo.is-loud { background: var(--gold); border-color: var(--gold); color: var(--ink); font-weight: 800; }
.panel-close {
  font: inherit; font-weight: 700; cursor: pointer; margin-top: 10px;
  display: block; width: 100%; min-height: 46px; border-radius: 999px;
  background: var(--ink); color: #fff; border: 0;
}
#hunt-app .btn-ghost-ink {
  background: none; color: var(--ink); border: 1.5px solid rgba(34,31,26,.25);
}
#hunt-app .btn-ghost-ink:hover { background: var(--ivory-deep); }

/* ---------- toast, banner, rest ---------- */
.hunt-toast {
  display: block; position: fixed; left: 12px; right: 12px; bottom: 118px; z-index: 1400;
  background: var(--ink); color: #fff; border-radius: 12px;
  padding: 11px 16px; font-size: .92rem; font-weight: 700; text-align: center;
  box-shadow: 0 4px 20px rgba(34,31,26,.3);
}
@media (min-width: 700px) { .hunt-toast { left: 50%; right: auto; transform: translateX(-50%); max-width: 460px; } }

.hunt-banner {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  position: fixed; left: 10px; right: 10px; bottom: 112px; z-index: 1450;
  background: var(--card); border-radius: 14px; padding: 12px 14px;
  box-shadow: 0 6px 26px rgba(34,31,26,.28); border-left: 5px solid var(--green);
}
@media (min-width: 700px) { .hunt-banner { left: 50%; right: auto; transform: translateX(-50%); width: 520px; } }
.ban-thumb img { width: 54px; height: 54px; object-fit: cover; border-radius: 8px; }
.ban-body { flex: 1; min-width: 160px; font-size: .92rem; }
.ban-look { display: block; font-size: .84rem; color: var(--ink-soft); margin-top: 3px; }
.ban-btns { display: flex; gap: 10px; align-items: center; font-size: .86rem; font-weight: 700; }
.ban-x { font: inherit; font-weight: 800; cursor: pointer; background: var(--ivory-deep); border: 0; border-radius: 999px; padding: 8px 14px; min-height: 40px; }

.hunt-rest {
  display: flex; gap: 10px; align-items: center;
  position: fixed; left: 12px; right: 12px; bottom: 118px; z-index: 1350;
  background: var(--gold); color: var(--ink); border-radius: 12px;
  padding: 10px 14px; font-size: .9rem; font-weight: 600;
  box-shadow: 0 4px 18px rgba(34,31,26,.22);
}
.rest-x { font: inherit; cursor: pointer; background: none; border: 0; font-size: 1.3rem; line-height: 1; padding: 4px 8px; min-height: 40px; }

/* ---------- the bottom bar ---------- */
.hunt-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1300;
  background: rgba(250,246,239,.97); backdrop-filter: blur(8px);
  border-top: 1px solid rgba(34,31,26,.12);
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
}
.bar-progress { font-size: .88rem; font-weight: 800; color: var(--ink); text-align: center; }
.bar-rule {
  display: block; height: 4px; border-radius: 999px; margin: 5px auto 7px;
  max-width: 420px; background: rgba(34,31,26,.12); position: relative; overflow: hidden;
}
.bar-rule::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--pct, 0%); background: var(--green); transition: width .3s ease;
}
.bar-btns { display: flex; gap: 6px; justify-content: center; flex-wrap: nowrap; }
.bar-btns button {
  font: inherit; font-weight: 700; font-size: .8rem; cursor: pointer;
  padding: 8px 10px; min-height: 44px; border-radius: 999px;
  border: 1.5px solid rgba(34,31,26,.16); background: var(--card); color: var(--ink);
  white-space: nowrap;
}
.bar-gps.is-on { background: var(--teal); border-color: var(--teal); color: #fff; }
.bar-sound { flex: none; width: 46px; padding: 8px 0; }
.bar-share { background: var(--green); border-color: var(--green); color: #fff; }
/* Quiet, secondary, and ALWAYS visible. Its permanence is the whole point of
   the stopping-place design — most cards end here, and ending well is the
   feature. */
.bar-stop { color: var(--ink-soft); border-color: transparent; background: none; }
@media (max-width: 380px) { .bar-btns button { font-size: .74rem; padding: 8px 8px; } }

/* ---------- the finish sheet ---------- */
.hunt-finish {
  display: block; position: fixed; inset: 0; z-index: 1600;
  background: rgba(34,31,26,.55); overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 26px 12px calc(26px + env(safe-area-inset-bottom));
}
.finish-inner {
  max-width: 560px; margin: 0 auto; background: var(--ivory);
  border-radius: var(--radius); padding: 26px 22px 24px; box-shadow: 0 10px 40px rgba(0,0,0,.35);
}
.finish-inner h3 { font-size: clamp(1.5rem, 5.6vw, 2.1rem); margin-bottom: 8px; }
.finish-inner p { color: var(--ink-soft); margin-bottom: 12px; }
.finish-sub { font-size: .84rem; font-weight: 700; letter-spacing: .04em; color: var(--green); }
.finish-inner h4 { font-family: "Fraunces", Georgia, serif; font-size: 1.1rem; margin: 18px 0 8px; }
.finish-roll { list-style: none; margin: 0 0 8px; padding: 0; font-size: .92rem; }
.finish-roll li { padding: 5px 0; border-bottom: 1px solid rgba(34,31,26,.08); }
.finish-roll li span { font-weight: 800; color: var(--green); margin-right: 8px; }
.finish-png { margin: 18px 0; }
.finish-png img { width: 100%; height: auto; border-radius: 10px; box-shadow: var(--shadow); }
.finish-hold { font-size: .82rem; font-style: italic; color: var(--ink-soft); margin-top: 6px; }
.finish-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.finish-actions .btn { font-size: .9rem; padding: 11px 18px; }
.finish-cross { margin-top: 22px; padding-top: 16px; border-top: 1px solid rgba(34,31,26,.12); }
.finish-cross a { font-weight: 800; }
.finish-x2 {
  font: inherit; font-weight: 700; cursor: pointer; margin-top: 16px;
  display: block; width: 100%; min-height: 46px; border-radius: 999px;
  background: none; border: 1.5px solid rgba(34,31,26,.2); color: var(--ink-soft);
}
.hunt-canvas { display: none; }

/* The paper card's masthead and footers exist in the DOM at all times so that
   @media print — which cannot reorder anything — finds them already in the
   right places. On screen they are simply not there. */
.hunt-print-head, .hunt-print-foot { display: none; }

/* ---------- the memorial note ---------- */
.hunt-memorial {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  border-top: 5px solid var(--ink); padding: 28px 24px 26px; max-width: 780px;
}
.hunt-memorial h2 { font-size: clamp(1.4rem, 4.4vw, 1.9rem); margin-bottom: 14px; }
.hunt-memorial p { color: var(--ink-soft); margin-bottom: 14px; }
.hunt-memorial a { font-weight: 700; }
.hunt-memorial .mem-names {
  margin-top: 20px; padding-top: 14px; border-top: 1px solid rgba(34,31,26,.12);
  font-size: .86rem; font-weight: 700;
}

/* the one-line promo dropped onto murals.html and sculpture-zoo.html */
.hunt-promo { font-size: 1.02rem; }
.hunt-promo a { font-weight: 800; }

/* ---------- static prose on hunt.html ---------- */
.hunt-how { margin-top: 24px; }
.hunt-h3 { font-family: "Fraunces", Georgia, serif; font-size: 1.3rem; margin: 34px 0 10px; }
.hunt-decklist { max-width: 760px; }
.hunt-decklist dt { font-weight: 800; color: var(--green); margin-top: 12px; }
.hunt-decklist dd { margin: 2px 0 0; color: var(--ink-soft); font-size: .97rem; }

@media (min-width: 760px) {
  .hunt-grid { gap: 12px; }
  .roll-thumb { width: 96px; }
  .roll-thumb img { width: 96px; height: 96px; }
}

/* ══════════════════════════════════════════════════════════ the paper card ══
   Two pages on purpose: the CARD, and the STORIES to read out loud.
   No separate render path and no PDF — @media print prints the card in its
   CURRENT state, so a family can print a fresh one on Saturday morning or
   print their finished one on Saturday night as a keepsake.

   ☠️ NO print-color-adjust ANYWHERE. It is honoured by roughly half the
   engines, and a property that only half-works is not a plan. Every signal on
   this page is a border, a glyph or a font weight — never a fill — so a printer
   that strips colour loses nothing at all.
   ══════════════════════════════════════════════════════════════════════════ */
@media print {
  body.hunt-page .site-header,
  body.hunt-page footer,
  body.hunt-page .hunt-top,
  body.hunt-page .hunt-noprint,
  body.hunt-page .hunt-chooser,
  body.hunt-page .hunt-bar,
  body.hunt-page .hunt-panel,
  body.hunt-page .hunt-banner,
  body.hunt-page .hunt-toast,
  body.hunt-page .hunt-rest,
  body.hunt-page .hunt-finish,
  body.hunt-page .hunt-month,
  body.hunt-page .hunt-resume,
  body.hunt-page .hunt-headrow,
  body.hunt-page .hunt-codenote,
  body.hunt-page .hunt-codestrip,
  body.hunt-page .hunt-cardhead,
  body.hunt-page .hunt-momentnote,
  body.hunt-page .hunt-privacy,
  body.hunt-page .hunt-printbox,
  body.hunt-page .hunt-canvas,
  body.hunt-page .hunt-noscript,
  body.hunt-page .hunt-memorial,
  body.hunt-page .sq-more,
  body.hunt-page .sq-car,
  body.hunt-page .sq-stamp,
  body.hunt-page .roll-thumb,
  body.hunt-page .roll-check,
  body.hunt-page .roll-links,
  body.hunt-page .hunt-sq .sq-shot { display: none !important; }

  body.hunt-page .hunt-print-head,
  body.hunt-page .hunt-print-foot { display: block !important; }

  body.hunt-page { background: #fff !important; color: #000 !important; font-size: 10.5pt; padding-bottom: 0; }
  body.hunt-page section { padding: 0 !important; }
  body.hunt-page .wrap { max-width: none; padding: 0; }
  @page { size: letter portrait; margin: 12mm; }

  body.hunt-page .hunt-print-head { margin-bottom: 4mm; }
  body.hunt-page .ph-top {
    font-family: "Fraunces", Georgia, serif; font-weight: 700; font-size: 20pt;
    color: #000; border-bottom: 1pt solid #000; padding-bottom: 2mm; position: relative;
  }
  /* Reserved, sized and positioned NOW so the QR code is a drop-in later and
     not a redesign. It is the single highest-value v1.1 addition here: nobody
     wants to type 33 characters off a piece of paper in a driveway. */
  body.hunt-page .ph-qr {
    position: absolute; right: 0; top: -2mm;
    width: 0.9in; height: 0.9in; border: .5pt solid #000; display: block;
  }
  body.hunt-page .ph-name { font-family: "Fraunces", Georgia, serif; font-weight: 700; font-size: 20pt; margin-top: 3mm; }
  body.hunt-page .ph-meta { font-size: 9.5pt; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; margin-top: 1mm; }
  body.hunt-page .ph-join { font-size: 8.5pt; margin-top: 2mm; max-width: 130mm; }

  /* ☠️ EXPLICIT MILLIMETRE ROWS. aspect-ratio inside a grid is unreliable in
     print engines, and the screen rule above uses it — so the printed card
     states its row heights outright rather than hoping. */
  body.hunt-page .hunt-grid { gap: 0; border: 1.2pt solid #000; break-inside: avoid; }
  body.hunt-page .hunt-grid[style*="--n:3"] { grid-auto-rows: 58mm; }
  body.hunt-page .hunt-grid[style*="--n:4"] { grid-auto-rows: 44mm; }
  body.hunt-page .hunt-grid[style*="--n:5"] { grid-auto-rows: 35mm; }
  body.hunt-page .hunt-cell {
    border: .6pt solid #000; border-radius: 0; box-shadow: none !important;
    background: #fff !important; padding: 2mm; break-inside: avoid; position: relative;
  }
  /* Explicit resets rather than `all: unset` — unsetting everything on a
     <button> inside a print stylesheet is exotic enough that engines disagree
     about it, and this is the one stylesheet nobody can preview on the phone
     that will print it. */
  body.hunt-page .hunt-sq,
  body.hunt-page .hunt-cell.is-free .sq-free,
  body.hunt-page .hunt-cell.is-moment .hunt-sq {
    display: block; width: 100%; height: 100%; position: relative;
    aspect-ratio: auto; padding: 0; border: 0; border-radius: 0;
    background: none !important; box-shadow: none !important;
    color: #000 !important; text-align: left; overflow: visible; transform: none;
  }
  body.hunt-page .sq-n {
    position: static; display: inline-flex; width: 5mm; height: 5mm; min-width: 5mm;
    padding: 0; border: 0; box-shadow: none; border-radius: 50%;
    background: #000 !important; color: #fff !important; font-size: 7pt;
  }
  body.hunt-page .sq-name {
    display: block; position: static; background: none !important; color: #000 !important;
    padding: 1mm 0 0; font-family: "Fraunces", Georgia, serif; font-weight: 700;
    -webkit-line-clamp: 2;
  }
  body.hunt-page .hunt-grid[style*="--n:3"] .sq-name { font-size: 12pt; }
  body.hunt-page .hunt-grid[style*="--n:4"] .sq-name { font-size: 10pt; }
  body.hunt-page .hunt-grid[style*="--n:5"] .sq-name { display: block; font-size: 8.5pt; }
  body.hunt-page .sq-name i { font-size: 7pt; }
  body.hunt-page .sq-sub { display: block; font-size: 6.5pt; color: #444; margin-top: .5mm; }
  body.hunt-page .sq-dare { display: block; font-size: 8pt; font-style: italic; margin-top: 1mm; }
  body.hunt-page .hunt-grid[style*="--n:5"] .sq-dare { display: none; }
  /* Deliberately oversized: a seven-year-old with a marker needs a target, and
     a big circle invites colouring in rather than a tidy check. */
  body.hunt-page .sq-tick {
    display: block; position: absolute; right: 0; bottom: 0;
    width: 0.4in; height: 0.4in; border: 1pt solid #000; border-radius: 50%;
  }
  body.hunt-page .sq-tick.is-inked { background: #000 !important; }
  body.hunt-page .hunt-cell.is-found .sq-name { font-weight: 400; }
  body.hunt-page .hunt-cell.is-free { background: #eee !important; }
  body.hunt-page .hunt-cell.is-free .sq-free span { font-size: 16pt; }
  body.hunt-page .hunt-cell.is-free .sq-free small { font-size: 7pt; }
  body.hunt-page .hunt-cell.is-moment .sq-moment { display: block; font-size: 8pt; font-style: italic; -webkit-line-clamp: 4; }
  body.hunt-page .hunt-cell.is-moment .sq-tag { display: none; }
  /* On screen the star is lifted out of the flow to buy the tile 20px of
     height it does not have. On paper there is room, so it goes back in line
     ahead of the instruction instead of sitting on top of it. */
  body.hunt-page .sq-star { position: static; opacity: 1; font-size: 10pt; }

  body.hunt-page .hunt-print-foot { margin-top: 4mm; font-size: 8pt; }
  body.hunt-page .pf-sign { font-size: 11pt; margin-bottom: 3mm; }
  body.hunt-page .pf-rule {
    display: inline-block; width: 45mm; border-bottom: .8pt solid #000; margin: 0 2mm;
  }
  body.hunt-page .pf-rule.pf-long { width: 75mm; }
  body.hunt-page .pf-mem { max-width: 165mm; margin-bottom: 2mm; }

  /* page 2 — the read-aloud page */
  body.hunt-page .hunt-roll { break-before: page; margin-top: 0; }
  body.hunt-page .roll-head { font-size: 16pt; margin-bottom: 3mm; }
  body.hunt-page .roll-row {
    display: block; background: none !important; box-shadow: none !important;
    border-bottom: .5pt solid #999; border-radius: 0;
    padding: 2mm 0; margin: 0; break-inside: avoid;
  }
  body.hunt-page .roll-text h3 { font-size: 11pt; }
  body.hunt-page .roll-text h3 a { color: #000 !important; }
  body.hunt-page .roll-n { font-size: 7pt; color: #000 !important; }
  body.hunt-page .roll-official, body.hunt-page .roll-species { font-size: 8pt; color: #333 !important; }
  body.hunt-page .roll-look { font-size: 9pt; color: #000 !important; }
  body.hunt-page .roll-look strong { color: #000 !important; }
  body.hunt-page a[href]::after { content: "" !important; }
}

/* ============================================================ OFFLINE LAYER
   The "save this trail" control under the map, the offline banner, and the
   new-version prompt. See js/offline.js and sw.js.
   ☠️ Both fixed elements sit ABOVE the map (Leaflet panes run to z-index 800)
   and clear of the iPhone home indicator via safe-area-inset. */

.aw-offline {
  margin: 18px auto 0;
  max-width: 640px;
  background: var(--card);
  border: 1px solid rgba(34, 31, 26, .10);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px 12px;
}
.aw-off-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.aw-off-btn {
  font-family: inherit; font-size: .95rem; font-weight: 700;
  color: #fff; background: var(--teal);
  border: 0; border-radius: 999px; padding: 10px 18px;
  cursor: pointer; transition: background .15s ease;
}
.aw-off-btn:hover { background: #21585f; }
.aw-off-btn:disabled { opacity: .65; cursor: default; }
.aw-off-btn.is-saved { background: var(--ivory-deep); color: var(--ink); }
.aw-off-btn.is-saved:hover { background: #e6dcc9; }
.aw-off-state { font-size: .88rem; color: var(--ink-soft); }
.aw-off-bar {
  margin-top: 10px; height: 6px; border-radius: 999px;
  background: var(--ivory-deep); overflow: hidden;
}
.aw-off-bar i {
  display: block; height: 100%; width: 0%;
  background: var(--teal); transition: width .25s ease;
}
.aw-off-note {
  margin: 10px 0 0; font-size: .84rem; line-height: 1.5; color: var(--ink-soft);
}

.aw-netbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1200;
  background: var(--ink); color: var(--ivory);
  font-size: .88rem; line-height: 1.45; text-align: center;
  padding: 11px 16px calc(11px + env(safe-area-inset-bottom));
}

.aw-update {
  position: fixed; z-index: 1201;
  left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 12px;
  background: var(--ink); color: var(--ivory);
  border-radius: 999px; padding: 9px 10px 9px 18px;
  box-shadow: 0 6px 24px rgba(34, 31, 26, .28);
  font-size: .9rem; max-width: calc(100vw - 32px);
}
.aw-update button {
  font-family: inherit; font-size: .88rem; font-weight: 700;
  color: var(--ink); background: var(--gold);
  border: 0; border-radius: 999px; padding: 7px 15px; cursor: pointer;
}
.aw-update button:hover { background: #c99436; }

/* When both are up, the pill sits above the bar rather than on top of it. */
.aw-netbar ~ .aw-update { bottom: calc(60px + env(safe-area-inset-bottom)); }

@media print { .aw-offline, .aw-netbar, .aw-update { display: none !important; } }
