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

:root {
  --navy:    #0d2240;
  --navy-mid:#163352;
  --gold:    #c8932a;
  --gold-lt: #e8b448;
  --cream:   #f5f0e8;
  --white:   #ffffff;
  --text:    #1a2a3a;
  --muted:   #5a6a7a;
  --border:  rgba(200,147,42,0.25);
}

body {
  font-family: 'Source Sans 3', sans-serif;
  background: var(--cream);
  color: var(--text);
  min-height: 100vh;
  overflow-x: hidden;
}

a { color: inherit; }

.banner {
  background: var(--gold);
  color: var(--navy);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  padding: 7px 16px;
}

nav.topnav {
  background: var(--navy);
  border-bottom: 3px solid var(--gold);
  padding: 10px 24px;
  position: sticky; top: 0; z-index: 100;
}

.nav-inner {
  max-width: 1100px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}

.nav-brand {
  display: flex; align-items: center; gap: 10px;
  font-family: 'Playfair Display', serif;
  color: var(--white);
  font-weight: 700; font-size: 1.05rem;
  text-decoration: none;
}

.nav-brand-seal {
  width: 32px; height: 32px; border-radius: 50%;
  border: 2px solid var(--gold);
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.05);
}

.nav-brand-seal svg { width: 18px; height: 18px; }

.nav-links {
  display: flex; gap: 4px; list-style: none;
  flex-wrap: wrap; align-items: center;
}

.nav-links > li > a {
  color: rgba(255,255,255,0.85);
  text-decoration: none;
  font-size: 0.85rem; font-weight: 600;
  letter-spacing: 0.04em;
  padding: 8px 12px; border-radius: 6px;
  transition: color 0.15s ease, background 0.15s ease;
  display: inline-block;
}

.nav-links > li > a:hover,
.nav-links > li > a.current { color: var(--gold-lt); background: rgba(255,255,255,0.06); }

.nav-links .has-sub { position: relative; }

.nav-links .has-sub > a::after {
  content: ' ▾'; font-size: 0.7em; opacity: 0.6;
}

.submenu {
  position: absolute; top: 100%; left: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: 3px solid var(--gold);
  border-radius: 8px;
  min-width: 240px;
  padding: 8px 0;
  box-shadow: 0 12px 32px rgba(13,34,64,0.18);
  list-style: none;
  opacity: 0; visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}

.nav-links .has-sub:hover .submenu,
.nav-links .has-sub:focus-within .submenu {
  opacity: 1; visibility: visible; transform: translateY(0);
}

.submenu a {
  color: var(--navy);
  font-weight: 500;
  padding: 8px 16px;
  display: block;
  font-size: 0.88rem;
  text-decoration: none;
}

.submenu a:hover { background: var(--cream); color: var(--gold); }

.hero {
  background: linear-gradient(160deg, var(--navy) 0%, var(--navy-mid) 60%, #1e4570 100%);
  padding: 56px 24px 64px;
  text-align: center;
  position: relative;
  overflow: hidden;
}

.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 110%, rgba(200,147,42,0.18) 0%, transparent 70%),
    url("data:image/svg+xml,%3Csvg width='60' height='60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 0 L60 30 L30 60 L0 30 Z' fill='none' stroke='rgba(255,255,255,0.03)' stroke-width='1'/%3E%3C/svg%3E");
  pointer-events: none;
}

.hero > * { position: relative; z-index: 1; }

.seal {
  width: 104px; height: 104px;
  margin: 0 auto 20px;
  border-radius: 50%;
  border: 3px solid var(--gold);
  background: rgba(255,255,255,0.07);
  display: flex; align-items: center; justify-content: center;
  position: relative;
  animation: fadeDown 0.7s ease both;
}

.seal svg { width: 58px; height: 58px; opacity: 0.85; }

.seal-ring {
  position: absolute; inset: -10px;
  border-radius: 50%;
  border: 1px solid rgba(200,147,42,0.35);
  animation: pulse 3s ease-in-out infinite;
}

@keyframes pulse {
  0%,100% { transform: scale(1);    opacity: 0.5; }
  50%      { transform: scale(1.04); opacity: 1;   }
}

.hero-label {
  font-size: 0.72rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--gold-lt);
  font-weight: 600; margin-bottom: 8px;
  animation: fadeDown 0.7s 0.1s ease both; opacity: 0;
}

.hero h1 {
  font-family: 'Playfair Display', serif;
  font-size: clamp(2.4rem, 7vw, 4.2rem);
  font-weight: 900; color: var(--white);
  line-height: 1.05; letter-spacing: -0.01em;
  animation: fadeDown 0.7s 0.2s ease both; opacity: 0;
}

.hero h1 span { color: var(--gold-lt); }

.hero-sub {
  font-size: 1rem; color: rgba(255,255,255,0.65);
  margin-top: 10px; letter-spacing: 0.04em; font-weight: 300;
  animation: fadeDown 0.7s 0.3s ease both; opacity: 0;
}

@keyframes fadeDown {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.divider {
  width: 64px; height: 3px;
  background: linear-gradient(90deg, var(--gold), var(--gold-lt));
  margin: 20px auto 0; border-radius: 2px;
  animation: fadeDown 0.7s 0.35s ease both; opacity: 0;
}

.hero.compact { padding: 44px 24px 52px; }
.hero.compact .seal { width: 80px; height: 80px; margin-bottom: 16px; }
.hero.compact .seal svg { width: 44px; height: 44px; }
.hero.compact h1 { font-size: clamp(1.9rem, 5vw, 3rem); }

.feature-wrap {
  padding: 0 16px; margin-top: -36px;
  position: relative; z-index: 10;
  animation: riseUp 0.65s 0.5s ease both; opacity: 0;
}

@keyframes riseUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.feature-card {
  max-width: 820px; margin: 0 auto;
  background: var(--white);
  border-radius: 14px;
  box-shadow: 0 12px 48px rgba(13,34,64,0.15);
  border-top: 4px solid var(--gold);
  padding: 40px 40px 36px;
  text-align: center;
}

.feature-eyebrow {
  font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 10px;
}

.feature-card h2 {
  font-family: 'Playfair Display', serif;
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  color: var(--navy); line-height: 1.2; font-weight: 700;
  margin-bottom: 12px;
}

.feature-card p {
  font-size: 1rem; color: var(--muted);
  line-height: 1.7; max-width: 600px;
  margin: 0 auto 22px;
}

.btn-primary {
  display: inline-block;
  background: var(--navy); color: var(--white);
  padding: 14px 30px; border-radius: 8px;
  text-decoration: none;
  font-weight: 700; font-size: 0.85rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, color 0.18s ease;
  border: 2px solid var(--navy);
}

.btn-primary:hover {
  background: var(--gold); border-color: var(--gold);
  color: var(--navy);
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(13,34,64,0.2);
}

.btn-ghost {
  display: inline-block;
  background: transparent; color: var(--navy);
  padding: 12px 26px; border-radius: 8px;
  text-decoration: none;
  font-weight: 700; font-size: 0.82rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 2px solid var(--gold);
  transition: background 0.18s ease, color 0.18s ease;
}

.btn-ghost:hover { background: var(--gold); color: var(--navy); }

.section {
  max-width: 1040px; margin: 56px auto 0;
  padding: 0 20px;
}

.section-head { text-align: center; margin-bottom: 34px; }

.section-head .eyebrow {
  font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 10px;
}

.section-head h2 {
  font-family: 'Playfair Display', serif;
  font-size: clamp(1.7rem, 3.4vw, 2.3rem);
  color: var(--navy); font-weight: 700;
}

.section-head .sub {
  color: var(--muted); margin-top: 8px;
  font-size: 0.98rem; max-width: 600px; margin-left: auto; margin-right: auto;
}

.dept-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
}

.dept-card {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 24px 22px;
  text-decoration: none;
  color: var(--navy);
  display: flex; flex-direction: column; gap: 10px;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
  box-shadow: 0 2px 8px rgba(13,34,64,0.06);
}

.dept-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 32px rgba(13,34,64,0.13);
  border-color: var(--gold);
}

.dept-icon {
  width: 44px; height: 44px; border-radius: 10px;
  background: #fff7e6;
  display: flex; align-items: center; justify-content: center;
  color: var(--gold);
}

.dept-icon svg { width: 22px; height: 22px; }

.dept-card h3 {
  font-family: 'Playfair Display', serif;
  font-size: 1.1rem; line-height: 1.25;
  color: var(--navy); font-weight: 700;
}

.dept-card p {
  font-size: 0.85rem; color: var(--muted);
  line-height: 1.55;
}

.dept-more {
  margin-top: auto; color: var(--gold);
  font-weight: 700; font-size: 0.78rem;
  letter-spacing: 0.1em; text-transform: uppercase;
}

.content {
  max-width: 820px; margin: 0 auto;
  padding: 0 20px;
}

.content h2 {
  font-family: 'Playfair Display', serif;
  color: var(--navy); font-weight: 700;
  font-size: clamp(1.4rem, 2.6vw, 1.8rem);
  margin: 32px 0 14px;
}

.content h3 {
  font-family: 'Playfair Display', serif;
  color: var(--navy); font-weight: 700;
  font-size: 1.2rem;
  margin: 24px 0 10px;
}

.content p {
  color: var(--text); font-size: 1rem;
  line-height: 1.75; margin-bottom: 14px;
}

.content ul, .content ol {
  margin: 6px 0 16px 22px;
  color: var(--text); line-height: 1.8;
}

.content li { margin-bottom: 4px; }
.content a { color: var(--gold); font-weight: 600; }
.content a:hover { text-decoration: underline; }

.content strong { color: var(--navy); font-weight: 700; }

.card {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 22px 24px;
  margin: 20px 0;
  box-shadow: 0 2px 10px rgba(13,34,64,0.06);
}

.card h3 {
  margin-top: 0;
  font-family: 'Playfair Display', serif;
  color: var(--navy); font-weight: 700;
  font-size: 1.15rem; margin-bottom: 8px;
}

.kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 20px;
  font-size: 0.95rem;
}

.kv dt { color: var(--gold); font-weight: 700; text-transform: uppercase; font-size: 0.74rem; letter-spacing: 0.1em; align-self: center; }
.kv dd { color: var(--text); }
.kv a { color: var(--navy); font-weight: 600; text-decoration: none; }
.kv a:hover { color: var(--gold); }

.call-out {
  background: #fff7e6;
  border-left: 4px solid var(--gold);
  padding: 14px 18px;
  border-radius: 6px;
  margin: 16px 0;
  font-size: 0.95rem;
  color: var(--text);
}

.info-strip {
  margin-top: 56px;
  background: var(--white);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 40px 20px;
}

.info-inner {
  max-width: 1040px; margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 28px;
}

.info-item {
  display: flex; gap: 14px; align-items: flex-start;
}

.info-item .ic {
  flex-shrink: 0;
  width: 42px; height: 42px; border-radius: 50%;
  background: #fff7e6; border: 2px solid var(--gold);
  display: flex; align-items: center; justify-content: center;
  color: var(--gold);
}

.info-item .ic svg { width: 18px; height: 18px; }

.info-item .lbl {
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--gold); margin-bottom: 4px;
}

.info-item h4 {
  font-family: 'Playfair Display', serif;
  color: var(--navy); font-size: 1.05rem;
  font-weight: 700; line-height: 1.3;
  margin-bottom: 2px;
}

.info-item a { color: var(--navy); text-decoration: none; }
.info-item a:hover { color: var(--gold); }

.info-item .sm {
  font-size: 0.85rem; color: var(--muted); line-height: 1.5;
}

footer {
  background: var(--navy);
  color: rgba(255,255,255,0.6); text-align: center;
  padding: 38px 20px 28px; font-size: 0.85rem; line-height: 1.8;
}

footer strong { color: var(--gold-lt); }
footer a { color: var(--gold-lt); text-decoration: none; }
footer a:hover { text-decoration: underline; }

.footer-seal {
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid rgba(200,147,42,0.4);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 14px;
}

.footer-links {
  display: flex; gap: 18px; flex-wrap: wrap;
  justify-content: center; margin: 8px 0 14px;
}

.footer-links a { font-size: 0.82rem; letter-spacing: 0.04em; }

.crumbs {
  max-width: 1040px; margin: 0 auto;
  padding: 14px 20px 0;
  font-size: 0.82rem; color: var(--muted);
}

.crumbs a { color: var(--gold); text-decoration: none; font-weight: 600; }
.crumbs a:hover { text-decoration: underline; }
.crumbs .sep { opacity: 0.5; margin: 0 6px; }

.page-body { padding-bottom: 60px; }

@media (max-width: 720px) {
  .nav-links { gap: 0; justify-content: center; }
  .nav-links > li > a { font-size: 0.78rem; padding: 6px 8px; }
  .submenu {
    position: static; opacity: 1; visibility: visible; transform: none;
    display: none; border-top: none; box-shadow: none;
    background: rgba(255,255,255,0.04); min-width: 0; margin: 4px 0;
    border: none; border-radius: 4px;
  }
  .nav-links .has-sub:hover .submenu,
  .nav-links .has-sub:focus-within .submenu { display: block; }
  .submenu a { color: rgba(255,255,255,0.85); }
  .submenu a:hover { background: rgba(255,255,255,0.1); color: var(--gold-lt); }
  .feature-card { padding: 28px 22px; }
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv dt { margin-top: 8px; }
}

/* ============================================================
   Components added when real photos and documents were ported
   over from the WordPress site. Uses the tokens defined above.

   Note on specificity: `.content ul` above sets a 22px left margin,
   which outranks a bare `.doc-list`. Component rules that live inside
   `.content` are therefore written as `.content .thing`.
   ============================================================ */

/* --- Photographic hero -------------------------------------- */
.hero.photo { padding: 0; }
.hero-photo {
  position: relative;
  min-height: 460px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: 72px 24px 64px;
  background-size: cover;
  background-position: center;
  background-color: var(--navy);
}
/* Two layers: an overall tint for colour consistency, plus a band behind the
   text so headlines stay legible over light photos (council chambers, library). */
.hero-photo::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(13,34,64,0.58) 0%, rgba(13,34,64,0.42) 45%, rgba(13,34,64,0.72) 100%);
}
.hero-photo::after {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: min(100%, 300px); transform: translateY(-50%);
  background: radial-gradient(ellipse at center,
    rgba(9,24,46,0.72) 0%, rgba(9,24,46,0.45) 55%, rgba(9,24,46,0) 78%);
}
.hero-photo > * { position: relative; z-index: 1; }
.hero-photo .hero-label {
  color: var(--gold-lt); text-shadow: 0 1px 10px rgba(0,0,0,0.5);
}
.hero-photo h1 {
  font-family: 'Playfair Display', serif;
  font-size: clamp(2rem, 5.4vw, 3.2rem);
  color: var(--white); line-height: 1.12; margin-bottom: 14px;
  text-shadow: 0 2px 20px rgba(0,0,0,0.55), 0 1px 3px rgba(0,0,0,0.4);
}
.hero-photo .hero-sub {
  color: #fff;
  max-width: 660px; font-size: 1.06rem; line-height: 1.6;
  text-shadow: 0 1px 12px rgba(0,0,0,0.65), 0 1px 3px rgba(0,0,0,0.5);
}
.hero-photo .hero-credit {
  margin-top: 20px; font-size: 0.72rem; letter-spacing: 0.06em;
  color: rgba(255,255,255,0.82); text-transform: uppercase;
  text-shadow: 0 1px 8px rgba(0,0,0,0.7);
}
.hero-photo .divider { margin-top: 22px; }
.hero.compact.photo .hero-photo { min-height: 330px; padding: 56px 24px 52px; }

/* --- Inline figures ----------------------------------------- */
.content figure { margin: 26px 0; }
.content figure img,
.content img { max-width: 100%; height: auto; display: block; border-radius: 6px; }
.content figure > img { width: 100%; }
.content figure figcaption {
  margin-top: 10px; font-size: 0.82rem; color: var(--muted); font-style: italic;
}

/* --- Two-column text + image -------------------------------- */
.content .split {
  display: grid; grid-template-columns: 1.1fr 0.9fr;
  gap: 40px; align-items: start; margin: 40px 0;
}
/* One ratio for every text+image split. Two ratios meant a photo was 536px
   wide in one section and 447px in the next on the same page, which reads as
   sloppy sizing rather than as a deliberate variation. */
.content .split.narrow-img { grid-template-columns: 1.1fr 0.9fr; }
/* Text-beside-text pairs read wrong when vertically centred — align the headings. */
.content .split.middle { align-items: center; }
.content .split.even { grid-template-columns: 1fr 1fr; }
/* Supporting photography is capped so a single image never towers over the
   paragraph it illustrates. */
.content .split > figure { margin: 0; }
.content .split > figure > img,
.content .split > img {
  width: 100%; height: auto; border-radius: 8px;
  aspect-ratio: 4 / 3; object-fit: cover;
  max-height: 340px; width: 100%;
}
.content .split > div > *:first-child { margin-top: 0; }
/* Logos are artwork on a background, not photography — never crop or bleed them. */
.content .split.poster > img,
.content .split.poster > figure > img {
  aspect-ratio: auto; object-fit: contain; max-height: 460px;
  background: var(--white); border: 1px solid var(--border); padding: 10px;
}
.content .split.logo > img {
  aspect-ratio: auto; object-fit: contain;
  background: var(--white); border: 1px solid var(--border);
  padding: 26px; max-height: 210px;
}

/* Short label lists (cuisine types, amenities) as chips rather than a thin
   bulleted column stranded beside empty space. */
.content .chips {
  list-style: none; margin: 18px 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px;
}
.chips li {
  background: var(--white); border: 1px solid var(--border);
  border-radius: 999px; padding: 8px 16px;
  font-size: 0.92rem; color: var(--navy); font-weight: 600; margin: 0;
}

/* --- Staff / official portraits ----------------------------- */
.content .staff-grid {
  display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  margin: 30px 0; padding: 0; list-style: none;
}
.staff-card { text-align: center; }
.staff-card img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 8px; background: var(--white);
  border: 1px solid var(--border);
}
.staff-card h4 {
  font-family: 'Playfair Display', serif;
  font-size: 1.02rem; color: var(--navy); margin-top: 12px; font-weight: 700;
}
.staff-card p { font-size: 0.8rem; color: var(--muted); margin-top: 2px; margin-bottom: 0; }

/* --- Signed message from an official ------------------------ */
.content .message {
  display: grid; grid-template-columns: 190px 1fr;
  gap: 28px; align-items: start;
  background: var(--white); border: 1px solid var(--border);
  border-left: 3px solid var(--gold);
  border-radius: 8px; padding: 26px 28px; margin: 34px 0;
}
.message > img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 8px;
}
.message .eyebrow {
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); font-weight: 700; margin-bottom: 8px;
}
.message h3 {
  font-family: 'Playfair Display', serif; color: var(--navy);
  font-size: 1.3rem; margin: 0 0 10px;
}
.message .signature {
  max-width: 180px; margin-top: 16px; opacity: 0.85; border-radius: 0;
}
.message .who { margin: 12px 0 0; font-weight: 700; color: var(--navy); }
.message .role { font-size: 0.82rem; color: var(--muted); margin: 2px 0 0; }
.message > div > *:last-child { margin-bottom: 0; }

/* --- Document / PDF lists ----------------------------------- */
.content .doc-list { list-style: none; margin: 18px 0; padding: 0; }
.content .doc-list li { margin: 0 0 6px; }
.doc-list a {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; background: var(--white);
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--navy); font-weight: 600; text-decoration: none;
  font-size: 0.92rem;
}
.doc-list a:hover { border-color: var(--gold); background: #fffdf8; }
.doc-list a::before {
  content: "PDF"; flex: none;
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.06em;
  color: var(--white); background: var(--gold);
  padding: 3px 6px; border-radius: 3px;
}
.content .doc-columns { columns: 2; column-gap: 18px; }
.doc-columns li { break-inside: avoid; }

/* --- Collapsible groups (ordinances, job listings) ---------- */
.accordion {
  background: var(--white); border: 1px solid var(--border);
  border-radius: 8px; margin-bottom: 10px; overflow: hidden;
}
.accordion > summary {
  cursor: pointer; padding: 15px 18px; font-weight: 700;
  color: var(--navy); list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.accordion > summary::-webkit-details-marker { display: none; }
.accordion > summary::after {
  content: "+"; color: var(--gold); font-size: 1.3rem; line-height: 1; font-weight: 400;
}
.accordion[open] > summary::after { content: "\2013"; }
.accordion > summary:hover { background: #fffdf8; }
.accordion .acc-body { padding: 4px 18px 18px; border-top: 1px solid var(--border); }
.accordion .acc-body > *:first-child { margin-top: 14px; }

/* --- Quick-link tiles --------------------------------------- */
.content .quicklinks, .quicklinks {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  margin: 26px 0; padding: 0; list-style: none;
}
.quicklinks a {
  display: flex; align-items: center; padding: 15px 18px; text-decoration: none;
  background: var(--navy); color: var(--white);
  border-radius: 8px; font-weight: 700; font-size: 0.84rem;
  letter-spacing: 0.04em; text-transform: uppercase; line-height: 1.35;
  border: 1px solid transparent;
}
.quicklinks a:hover { background: var(--navy-mid); border-color: var(--gold); color: var(--gold-lt); }

/* --- Facts row ---------------------------------------------- */
.content .facts {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin: 28px 0; padding: 0; list-style: none;
}
.fact {
  background: var(--white); border: 1px solid var(--border);
  border-radius: 8px; padding: 18px; text-align: center;
}
.fact strong {
  display: block; font-family: 'Playfair Display', serif;
  font-size: 1.5rem; color: var(--gold); margin-bottom: 4px;
}
.fact span { font-size: 0.82rem; color: var(--muted); }

/* --- Photo grid --------------------------------------------- */
.content .photo-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  margin: 30px 0; padding: 0; list-style: none;
}
.content .photo-grid figure { margin: 0; }
.photo-grid img {
  width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; border-radius: 8px;
}
.photo-grid figcaption { font-style: normal !important; font-size: 0.84rem; }

/* --- A note where a section has no documents yet ------------- */
.content .empty-note {
  background: var(--white); border: 1px dashed var(--border);
  border-radius: 8px; padding: 16px 18px; margin: 18px 0;
  color: var(--muted); font-size: 0.94rem; line-height: 1.6;
}

/* --- Rhythm ------------------------------------------------- */
/* 7 department cards read better as 4+3 than 3+3+1. */
@media (min-width: 1000px) {
  .dept-grid { grid-template-columns: repeat(4, 1fr); }
}
.page-body { padding-bottom: 34px; }
.page-body > .content > *:first-child { margin-top: 0; }
.section:last-of-type { margin-bottom: 40px; }

@media (max-width: 720px) {
  .hero-photo { min-height: 360px; padding: 52px 20px 44px; }
  .hero.compact.photo .hero-photo { min-height: 260px; padding: 42px 20px 38px; }
  .content .split,
  .content .split.narrow-img,
  .content .split.even { grid-template-columns: 1fr; gap: 22px; }
  .content .message { grid-template-columns: 1fr; gap: 18px; }
  .message > img { max-width: 180px; }
  .content .doc-columns { columns: 1; }
  .content .staff-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 16px; }
}

/* ============================================================
   Layout width system
   ------------------------------------------------------------
   The original design used four different container widths
   (nav 1100, section 1040, content 820, crumbs 1040), which left
   the page looking narrow on a normal desktop and made the
   breadcrumb sit out of line with the text beneath it.

   One container token now drives every band, and inside .content
   only running prose is held to a readable measure — grids, photo
   rows, document lists and cards use the whole container.
   ============================================================ */
:root { --page: 1280px; --mid: 1000px; --prose: 720px; }
/* --prose is deliberately a length, not `ch`: the ch unit resolves against each
   element's own font-size, so an h2 and a p sharing "74ch" get very different
   widths and their left edges stagger into a staircase. */

.nav-inner,
.section,
.crumbs,
.info-inner,
.page-body > .content,
.content { max-width: var(--page); }

.section { padding-left: 24px; padding-right: 24px; }
.content { padding-left: 24px; padding-right: 24px; }
.crumbs  { padding-left: 24px; padding-right: 24px; }

/* The homepage nests .content inside .section, so both the max-width and the
   24px gutter were applied twice: home measured 1184px of text against 1232px
   on every interior page, and its left edge sat 24px further in, so the column
   visibly shifted when you navigated home -> anywhere. The band is already
   established by .section; the inner .content must not re-establish it. */
.section > .content { max-width: none; padding-left: 0; padding-right: 0; }
.feature-card { max-width: 980px; }

/* Running prose stays readable; anything with a class is a component
   and is free to span the full container. */
.content > p,
.content > dl,
.content > blockquote,
.content > ul:not([class]),
.content > ol:not([class]),
.content > .call-out,
.content > .empty-note,
.content article > p,
.content article > ul:not([class]) { max-width: var(--prose); }

.content > h2, .content > h3 { max-width: var(--prose); }

/* Heading width tiers used to be reconciled here with a bank of :has() rules,
   because three centred tiers put a heading and the block it introduced on
   different left edges. The layout layer now left-aligns every block to one
   shared edge, so that whole class of mismatch cannot occur and the rules were
   deleted rather than left as dead weight. */

/* Centre the prose column. Left-aligning a 74ch measure inside a 1280px
   container strands ~580px of empty space on the right of every text-only
   section; centring balances it and reads as deliberate, while grids, photo
   rows and document lists still span the full container. */
.content > p,
.content > dl,
.content > blockquote,
.content > ul:not([class]),
.content > ol:not([class]),
.content > .call-out,
.content > .empty-note,
.content > h2,
.content > h3,
.content > figure,
.content article { margin-inline: auto; }

/* Photographs shouldn't grow to the full container — cap them so a
   single figure never dominates the page. */
.content > figure { max-width: 780px; }
.content > figure > img { max-height: 460px; object-fit: cover; }

/* Three width tiers keep the rhythm coherent: running prose at --prose,
   inline components (button rows, single-column document lists, message cards)
   at --mid, and true grids at the full container. Without the middle tier a
   three-button row jumps straight from a 720px paragraph to 1280px and reads
   as a different page. */
.content > .quicklinks,
.content > .message,
.content > .accordion,
.content > .doc-list:not(.doc-columns),
.content > details.accordion {
  max-width: var(--mid); margin-inline: auto;
}

/* Wide containers give long document lists room for a third column. */
@media (min-width: 1100px) {
  .content .doc-columns { columns: 3; }
}

/* Equal-width tiles. auto-fill (not auto-fit) keeps empty tracks, so when the
   last row holds a single item it stays one column wide instead of stretching
   to the full width and dwarfing its neighbours. */
.content .quicklinks, .quicklinks {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.quicklinks a { justify-content: center; text-align: center; }

/* Community links read as tiles too, not bare bullets. */
.content .link-tiles {
  list-style: none; margin: 20px 0; padding: 0;
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.link-tiles a {
  display: block; padding: 13px 16px; text-decoration: none;
  background: var(--white); border: 1px solid var(--border);
  border-radius: 6px; color: var(--navy); font-weight: 600; font-size: 0.94rem;
}
.link-tiles a:hover { border-color: var(--gold); background: #fffdf8; }
.link-tiles a::after { content: " \2197"; color: var(--gold); font-weight: 700; }

@media (max-width: 900px) {
  .content > p, .content > dl, .content > h2, .content > h3,
  .content > ul:not([class]), .content > ol:not([class]),
  .content > .call-out, .content > .empty-note,
  .content article > p, .content > figure { max-width: none; }
}

/* --- Motion preferences ------------------------------------- */
/* The hero and feature card animate in from opacity:0. Respect a reader's
   reduced-motion setting and show the content immediately instead. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Tablet nav --------------------------------------------- */
/* The base stylesheet only switches the nav to its stacked form below 720px.
   Between 720 and ~900 the inline nav is too tight and the absolutely
   positioned Services submenu runs off the right edge, so its links open
   off-screen. Apply the stacked treatment up to 900px instead. */
@media (max-width: 900px) {
  .nav-inner { flex-wrap: wrap; justify-content: center; gap: 8px; }
  .nav-links { gap: 0; justify-content: center; flex-wrap: wrap; }
  .nav-links > li > a { font-size: 0.78rem; padding: 6px 8px; }
  .submenu {
    position: static; opacity: 1; visibility: visible; transform: none;
    display: none; border-top: none; box-shadow: none;
    background: rgba(255,255,255,0.04); min-width: 0; margin: 4px 0;
    border: none; border-radius: 4px;
  }
  .nav-links .has-sub:hover .submenu,
  .nav-links .has-sub:focus-within .submenu { display: block; }
  .submenu a { color: rgba(255,255,255,0.85); }
  .submenu a:hover { background: rgba(255,255,255,0.1); color: var(--gold-lt); }
}

/* --- Long unbreakable strings ------------------------------- */
/* Email addresses and URLs must not push a narrow layout sideways. */
.info-item h4, .info-item a,
.kv dd, .kv dd a,
.doc-list a, .link-tiles a,
.content a { overflow-wrap: anywhere; }

/* --- Link affordance in definition lists --------------------- */
/* .kv a was navy/600/no-underline while a plain .kv dd is navy/400 — two
   near-identical darks, so font-weight alone marked a link. The library's map,
   phone, email and catalogue links, and every department phone number, read as
   ordinary text with nothing inviting a click. Weight is not a link affordance,
   and colour alone would still fail WCAG 1.4.1, so underline them outright and
   keep the existing gold hover. */
.kv a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: rgba(13, 34, 64, 0.4);
}
.kv a:hover { text-decoration-color: currentColor; }

/* --- Hero background video ---------------------------------- */
/* The video sits behind the scrim and above the poster background. It only
   loads on large screens (see the inline loader), so the poster carries the
   hero on phones and for readers who prefer reduced motion. */
.hero-media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s ease;
  z-index: 0; pointer-events: none;
}
.hero-media.is-playing { opacity: 1; }
.hero-video .hero-photo::before {
  background: linear-gradient(180deg,
    rgba(13,34,64,0.68) 0%, rgba(13,34,64,0.55) 45%, rgba(13,34,64,0.80) 100%);
}
.hero-video .hero-photo::after {
  background: radial-gradient(ellipse at center,
    rgba(9,24,46,0.80) 0%, rgba(9,24,46,0.55) 55%, rgba(9,24,46,0) 78%);
}
@media (prefers-reduced-motion: reduce) {
  .hero-media { display: none; }
}

/* --- Button parity ------------------------------------------ */
/* .btn-primary and .btn-ghost were authored with different padding
   (14/30 vs 12/26) and font sizes, so a pair sitting side by side rendered
   51px and 46px tall with misaligned baselines. Normalise the box so any
   combination of the two lines up. */
.btn-primary, .btn-ghost {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 52px; padding: 0 30px;
  font-size: 0.85rem; line-height: 1.2;
  border-width: 2px; border-style: solid;
  vertical-align: top; text-align: center;
}
.btn-primary { border-color: transparent; }

/* Document rows in the multi-column lists must share a baseline grid, so a
   two-line title never leaves its neighbours looking undersized. */
.content .doc-columns {
  columns: auto;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 18px; align-items: stretch;
}
@media (min-width: 1100px) {
  .content .doc-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.content .doc-columns li { margin: 0; }
.doc-columns a { height: 100%; }
/* ============================================================
   Tonkawa — modern layer (2026 refresh)
   ============================================================
   Loaded AFTER site-base.css and site-additions.css. It keeps every
   structural rule from those files — especially the container/width tier
   system and the heading-alignment rules — and restyles the surface:
   palette, type, elevation, rhythm and motion.

   Why a third layer rather than an edit in place: site-base.css is the
   original design system and site-additions.css carries fixes that were each
   a reported defect. Layering keeps those intact and reversible — drop this
   file from the concatenation and the previous design returns exactly.
   ============================================================ */

/* --- Palette ------------------------------------------------- */
/* Built around the vector brandmark (Tonkawa-Together-Badge.svg): orange
   #F16823, teal #009EA5, wheat #FCB614. An earlier pass made the site
   near-black with an orange-to-yellow gradient running through it, which was
   both heavy and in direct competition with the logo. This one takes the
   logo's teal as the site's voice — orange's complement, so the mark reads as
   the accent it is — and keeps the page light. */
:root {
  /* The logo's own three colours, kept for decorative use only. */
  --brand-orange: #F16823;
  --brand-teal:   #009EA5;
  --brand-yellow: #FCB614;

  /* Teal carries the site. It is the logo's second colour and the complement
     of its orange, so the mark sits on it and pops rather than competing, and
     it lets the page be light instead of black. Measured: white on --ink is
     11.80:1, --link on paper 8.23:1, --clay small caps 5.92:1. The logo orange
     is 3.01:1 on paper, so it is never used for text — only as an accent
     shape, the hairline rule, and the labyrinth's inner rings. */
  --ink:      #073E43;
  --ink-2:    #0A555C;
  --ink-3:    #0C6B73;
  --ink-4:    #0E8189;

  /* Legacy names kept so untouched rules inherit the new palette. --amber and
     --sunset now point at teal; the old amber/orange gradient is gone. */
  --amber:    #0E8189;
  --amber-lt: #8FD7D3;
  --sunset:   #0C6B73;
  --clay:     #A8410F;
  --teal:     #009EA5;
  --teal-dk:  #0A555C;

  --paper:    #FCFBF8;
  --paper-2:  #F1EEE7;
  --paper-3:  #E9F2F1;
  --surface:  #FFFFFF;

  --text:     #2A3739;
  --muted:    #5C6A6C;
  --line:     rgba(30,42,44,0.12);
  --line-2:   rgba(30,42,44,0.20);

  --link:     #0A555C;
  --link-ink: #8FD7D3;

  /* Flat and near-flat. The orange-to-yellow gradient that used to run through
     the buttons, icons, banner and nav pill is gone. */
  --grad-sun:  linear-gradient(135deg, #0C6B73 0%, #0E8189 100%);
  --grad-ink:  linear-gradient(160deg, #073E43 0%, #0A555C 100%);
  --grad-line: linear-gradient(90deg, #0E8189 0%, #009EA5 55%, #F16823 100%);

  --sh-1: 0 1px 2px rgba(7,62,67,.05), 0 2px 8px rgba(7,62,67,.05);
  --sh-2: 0 4px 12px rgba(7,62,67,.07), 0 12px 30px rgba(7,62,67,.09);
  --sh-3: 0 14px 30px rgba(7,62,67,.13), 0 30px 64px rgba(7,62,67,.15);

  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 34px;

  --ease: cubic-bezier(.22,.61,.36,1);

  /* Remap the original tokens so every untouched component in the base
     sheet inherits the new palette instead of needing a rule here. */
  --navy:     var(--ink);
  --navy-mid: var(--ink-3);
  --gold:     var(--link);
  --gold-lt:  var(--amber-lt);
  --cream:    var(--paper);
  --white:    var(--surface);
  --border:   var(--line);
}

/* --- Typography ---------------------------------------------- */
/* Fraunces for display: a variable serif with real character that reads as
   contemporary rather than institutional. Inter for everything else — it
   holds up at the small sizes a documents-heavy site depends on. */
body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--paper);
  color: var(--text);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Form controls do not inherit font-family from their ancestors -- the UA sets
   its own (Arial here). The inputs happened to be covered by an explicit rule,
   but <button> never was, so the contact form's "Send message" shipped in Arial
   while every other button on the site was Inter (those are <a> tags, which do
   inherit). The nav's search and hamburger buttons are icon-only so nothing was
   visible there, but they were equally unstyled. */
button, input, select, textarea { font-family: inherit; }

h1, h2, h3, h4,
.hero h1, .hero-photo h1,
.feature-card h2, .section-head h2,
.content h2, .content h3, .dept-card h3, .card h3 {
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.12;
  color: var(--ink);
}

/* Sizes only — the margins are set in the layout block below, which is the one
   place horizontal margins for .content children are decided. */
.content h2 { font-size: clamp(1.65rem, 2.9vw, 2.15rem); }
.content h3 { font-size: clamp(1.2rem, 1.9vw, 1.4rem); }
.content p  { font-size: 1.02rem; line-height: 1.75; color: var(--text); }
/* The opening paragraph carries a little more weight than the rest — it is the
   standfirst on almost every page. */
.content > p:first-of-type { font-size: 1.14rem; line-height: 1.7; color: var(--ink-2); }

/* Running-text links are underlined from the start. Colour alone is not a
   sufficient affordance, and this is the same reason .kv links were fixed. */
.content a {
  color: var(--link);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-color: rgba(10,85,92,.35);
  transition: text-decoration-color .18s var(--ease), color .18s var(--ease);
}
.content a:hover { text-decoration-color: currentColor; color: var(--clay); }
.content strong { color: var(--ink); font-weight: 650; }

/* ============================================================
   One left edge
   ============================================================
   The width system had three tiers — prose, mid, full — each CENTRED inside
   the container. Centring different widths guarantees different left edges, so
   on a long page like Residents the headings, paragraphs, photo rows and
   document lists started at four separate x positions and the column visibly
   jumped as you read down. Earlier work patched the symptom by promoting each
   heading to the tier of the block beneath it; that fixed heading-to-block
   pairs but left the page-level stagger untouched.

   The structural fix is to left-align every block to one shared edge. Prose
   still gets a readable measure and wide components still span the container —
   but the left edge never moves, which is the thing the eye actually tracks. */
/* ONE width for text, centred.

   Two earlier attempts both failed, in opposite directions. Centring three
   different tier widths put headings, paragraphs and photo rows on four
   different left edges — the column visibly jumped. Left-aligning them all to a
   shared edge cured the jump but left every short block trailing dead space on
   its right.

   Both problems come from the same cause: blocks of DIFFERENT widths. So text
   now has a single width and is centred, which makes stagger arithmetically
   impossible and puts any leftover space symmetrically in the margins where it
   reads as page margin instead of as a hole. Only non-text blocks — photo and
   staff grids, column lists, the contact split — open out wider, and those read
   as deliberate because they are visibly components, not prose. */
/* --wide drives the component band in the .content grid below, and is FLUID:
   a fixed 1280 still left a photo row looking like a strip on a 1600+ screen.
   min() keeps it to the viewport minus a gutter on smaller windows and caps it
   at 1560 so components stop growing on very wide monitors.

   --prose stays 840. At 17px that is already ~95 characters; widening running
   text further is measurably worse to read, so the page is made to feel full
   by what the COMPONENTS do, not by stretching paragraphs. */
:root {
  --page: 840px; --mid: 840px; --prose: 840px;
  /* 48px total gutter = 24px a side, which is exactly the nav's own gutter,
     so a section heading lines up with the wordmark above it instead of
     merely sitting near the edge. Capped at 1872 (1920 minus the gutter) so
     content stops growing on very large monitors. */
  --wide: min(1872px, 100% - 48px);
}

/* The nav is a utility bar, not a reading column — it spans the full viewport
   so the wordmark sits hard left and the search control hard right. Inheriting
   the content measure both boxed it in and pushed the links to a second row. */
.nav-inner { max-width: none; width: 100%; }

/* These carried `margin-inline: auto` to centre themselves in the old flow
   layout. .content is now a grid that places them, and an auto inline margin
   on a grid item shrink-wraps it to its content instead -- which centred every
   heading over its own text. The grid column does the centring now.

   NOTE this reverses an older rule of thumb ("never write `margin: X 0 Y` in
   .content"). That was true while centring depended on the auto margin; under
   the grid, inline margins must be 0 or blocks stop filling their band. */
.content > p,
.content > dl,
.content > blockquote,
.content > ul:not([class]),
.content > ol:not([class]),
.content > .call-out,
.content > .empty-note,
.content > h2,
.content > h3,
.content > figure,
.content article,
.content > .quicklinks,
.content > .message,
.content > .accordion,
.content > .doc-list,
.content > .doc-list:not(.doc-columns),
.content > details.accordion { margin-inline: 0; }

/* ============================================================
   Full-bleed content grid
   ============================================================
   These components were already told `max-width: var(--wide)` -- but .content
   was a fixed 820px box, and a child cannot exceed its parent's content box
   with max-width alone. So every "wide" component silently rendered at the
   text measure and the interior pages read as one narrow column stranded in a
   wide window, which is exactly what they looked like.

   .content is now a grid of nested column bands: `text` for prose, `wide` for
   components, `full` for bands that run to the page edge. Text still has ONE
   width and is centred, so left edges cannot stagger -- the fault that took
   three attempts to settle. Components opt out by name only.

   Deliberately no `100vw` and no `-50vw` negative-margin bleed: viewport units
   include the scrollbar gutter, so both make the document wider than the
   viewport. The bands here are all `%`-based and cannot overflow. */
.page-body > .content,
.content {
  display: grid;
  grid-template-columns:
    [full-start] minmax(20px, 1fr)
    [wide-start] minmax(0, calc((var(--wide) - var(--prose)) / 2))
    [text-start] min(var(--prose), 100% - 40px) [text-end]
    minmax(0, calc((var(--wide) - var(--prose)) / 2)) [wide-end]
    minmax(20px, 1fr) [full-end];
  max-width: none;
  padding: 0;
}
.content > * { grid-column: text; }

/* Components that are grids or panels rather than prose.

   They start on the SAME left edge as the text and extend right into the wide
   band, rather than being centred in it. Centring them looked obvious but put
   every component 220px left of the body text, so a section heading at one x
   sat directly above a split's own heading at another -- the staircase that was
   rejected twice before. One left edge for everything; only the right edge
   varies, and it varies on components, never on prose. */
.content > .staff-grid,
.content > .photo-grid,
.content > .doc-columns,
.content > .link-tiles,
.content > .chips,
.content > .split,
.content > .job-list,
.content > .contact-split,
.content > .job-tools,
.content > .job-count,
.content > .facts,
.content > figure {
  grid-column: text-start / wide-end;
  max-width: none;
}

/* Now that a split runs the full component band its photo is often taller than
   the copy beside it, which left the text hanging at the top with a block of
   empty space beneath. Centre the pair -- but only when the far side really is
   a picture. The existing `.middle` opt-in stays for text-beside-text splits,
   where centring misaligns the two headings. */
.content .split:has(> img),
.content .split:has(> figure) { align-items: center; }

/* ============================================================
   Section bands
   ============================================================
   build.py:panes() wraps each top-level h2 and its content in .pane. Each one
   is a full-bleed band: it runs edge to edge, alternate bands carry a tint, and
   its contents line up on the same grid as the rest of the page via subgrid.

   Bands, not rules or boxes, are what separate sections here. A hairline is
   easy to miss on a long page and a card around every section looks like a
   dashboard; a change of ground is unmistakable and completely quiet.

   An earlier attempt put the heading in a sticky left rail. It used the width
   but read as a sidebar rather than as a page, and was rejected. Headings now
   sit where you would expect them -- above their section, on the page gutter. */
.content > .pane {
  grid-column: full;
  display: grid;
  grid-template-columns: subgrid;
  padding-block: 62px;
  position: relative;
}
/* .pane-body is `display: contents` so its children become items of the pane's
   subgrid directly -- without that, text and photos in one section cannot take
   different widths.

   EVERYTHING in a section starts on the same left edge: the heading, the prose,
   the tiles, the photos. An earlier pass centred the heading and text in the
   reading column while components took the full band, which put a heading at
   x=300 directly above its own buttons at x=24. It looked like a mistake
   because it was one. One edge, always. */
.pane-body { display: contents; }
.content > .pane > *,
.pane-body > * { grid-column: wide; }
.content > .pane > h2 { grid-column: wide; margin: 0 0 22px; }

/* Running text keeps a readable measure inside that band. */
.pane-body > p,
.pane-body > ul:not([class]):not(:has(> li > a)),
.pane-body > ol:not([class]),
.pane-body > dl,
.pane-body > .call-out,
.pane-body > blockquote,
.pane-body > h3,
.pane-body > h4 { max-width: var(--prose); }

.pane-body > *:first-child { margin-top: 0; }

/* Every section opened at the same weight, which is why a nine-section page
   read as one undifferentiated run. The lead paragraph now carries the same
   standfirst treatment the page's opening paragraph already had, so a section
   has a top and a body instead of being uniform grey. */
.pane-body > p:first-of-type {
  font-size: 1.12rem;
  line-height: 1.72;
  color: var(--ink-2);
}


/* A section that is only words cannot fill a 1550px band at a readable line
   length: held to one column it leaves 700px of nothing to its right, which
   reads as a hole rather than as margin. Two columns use the width with real
   content. .pane-text is set by build.py -- see panes() for why not :has(). */
.pane-text > .pane-body {
  display: block;          /* `display: contents` has no box for columns */
  grid-column: wide;
  columns: 2;
  column-gap: 72px;
}
.pane-text > .pane-body > * {
  max-width: none;
  break-inside: avoid;
}
.pane-text > .pane-body > h3,
.pane-text > .pane-body > h4 { break-after: avoid; }

/* ---- Link lists become tiles --------------------------------
   A section's links were plain bullets: the Parks list, the ballfield
   schedules, the Healthy Living helplines. Half a dozen bullets in a 1550px
   band is the single thing that made these pages look unfinished, and they are
   navigation, not prose. As tiles they fill the band and read as things to
   click. Only lists whose items are ONLY links convert -- a real prose list
   must stay a prose list. */
.pane-body > ul:not([class]):has(> li > a) {
  list-style: none;
  max-width: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}
.pane-body > ul:not([class]):has(> li > a) > li { margin: 0; }
.pane-body > ul:not([class]):has(> li > a) > li > a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 62px;
  padding: 14px 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  transition: transform .18s var(--ease), box-shadow .22s var(--ease),
              border-color .18s var(--ease);
}
.pane-body > ul:not([class]):has(> li > a) > li > a::after {
  content: "→";
  color: var(--clay);
  font-weight: 400;
  transform: translateX(0);
  transition: transform .22s var(--ease);
}
.pane-body > ul:not([class]):has(> li > a) > li > a:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-2);
  border-color: var(--brand-teal);
  color: var(--ink);
}
.pane-body > ul:not([class]):has(> li > a) > li > a:hover::after { transform: translateX(4px); }

/* ---- Contact pairs become a card -----------------------------
   `.kv` is how every phone number, address and email on the site is marked up.
   Loose in a band it read as two stray lines of small text. A bordered card
   gives it edges and makes it findable, which for a city phone number is the
   whole job. */
.pane-body .kv {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  padding: 22px 26px;
  width: fit-content;
  min-width: min(100%, 340px);
  max-width: min(100%, 620px);
  gap: 12px 28px;
  margin: 24px 0 0;
}

/* Lead paragraph and contact card, side by side. Stacked, the card sat under
   the text with the right half of the band empty beside it. */
.lead-split {
  grid-column: wide;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.5fr);
  gap: 20px 56px;
  align-items: start;
}
.lead-split > div > p { max-width: var(--prose); }
.lead-split > .kv { margin-top: 0; }
@media (max-width: 900px) {
  .lead-split { grid-template-columns: 1fr; }
}

/* Alternate ground. --paper-2 is the same tint the home page bands already use,
   so the interior pages pick up the rhythm the landing page had. */
.content > .pane:nth-of-type(even) { background: var(--paper-2); }

/* Zig-zag. Every photo on a page pointing the same way is what made these
   pages feel like a list; alternating the side gives the eye somewhere to go.
   The .flip class is applied to every second split by build.py:flip_splits(),
   counted across the whole page -- doing it per section leaves two splits in
   the same section facing the same way. `order` moves the picture without
   touching the markup, and the column ratio swaps with it so the photo stays
   the narrower half in both directions. */
.content .split.flip { grid-template-columns: 0.9fr 1.1fr; }
.content .split.flip > img,
.content .split.flip > figure { order: -1; }

@media (max-width: 1000px) {
  .content > .pane { padding-block: 44px; }
  .content > .pane > h2 { margin-bottom: 18px; }
  /* One column on a phone, and the photo goes back above its copy in both
     directions -- a zig-zag has no meaning in a single column. */
  .content .split.flip > img,
  .content .split.flip > figure { order: 0; }
}

.content h2 { margin: 52px 0 16px; }
.content h3 { margin: 34px 0 10px; }
.content > *:first-child { margin-top: 0; }

/* Paired calls to action get one footprint. Left to their labels they measured
   153px and 205px, which reads as a mistake rather than as hierarchy. */
.feature-card .btn-primary,
.feature-card .btn-ghost { min-width: 216px; justify-content: center; }

/* The homepage service pills are a centred landing row, not a left-aligned
   inline component. Held to the 860px mid measure they broke onto two lines
   inside a 1140px band that had room for all five. */
/* Flex, not the grid the component uses elsewhere. The grid lays out auto-fill
   tracks, so `justify-content: center` centres the track set and a lone pill on
   the last row still sits hard left. Flex centres every line, including the
   last, and `flex: 0 0 auto` keeps a single pill from stretching — which is the
   same failure the grid's auto-fill (rather than auto-fit) was chosen to avoid. */
.section > .content > .quicklinks {
  max-width: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}
.section > .content > .quicklinks > a { flex: 0 0 auto; }

/* The two closing blocks on the homepage. They used to share a two-column split
   — the tribal note squeezed beside an unrelated link list, both ragged — and
   then sat as two untinted centred rows, which read as an afterthought. Each is
   now a full-width band on its own ground: warm sand for the heritage note,
   a teal wash for the wayfinding links, so the page ends on two deliberate
   blocks rather than trailing off. */
.home-band { padding: 68px 24px 74px; text-align: center; }
.home-band-inner { max-width: var(--page); margin-inline: auto; }
.home-band h2 { margin: 0 0 14px; }
.home-band p { max-width: 620px; margin: 0 auto 12px; color: var(--text); }
.home-band .eyebrow {
  color: var(--clay); letter-spacing: .18em; font-weight: 600;
  font-size: .72rem; text-transform: uppercase; margin-bottom: 10px;
}

.home-band-sand {
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* The Tonkawa Tribe's own mark, on the block about the tribe and the city
   sharing one idea of home. It is a horizontal lockup (390x100), so it is sized
   by width — the square treatment the community roundel used would squash it. */
.home-band-mark {
  display: block; margin: 0 auto 22px;
  width: min(300px, 72vw); height: auto;
}

/* Runs straight into the info strip below it — the sliver of paper between the
   two bands read as a gap rather than as breathing room. The eyebrow alone
   heads this block now; "Also on this site" restated what the links already
   showed. */
.home-band-teal {
  background:
    radial-gradient(90% 120% at 50% 0%, rgba(0,158,165,.12) 0%, rgba(0,158,165,0) 70%),
    var(--paper-3);
  padding-bottom: 62px;
  margin-bottom: 0;
}
.home-band-teal + .info-strip,
.home-band-teal + * { margin-top: 0; }
.home-band-teal .link-tiles { margin-top: 20px; }
/* Wide enough for four 262px pills plus their gaps (1084px) so they sit on one
   row; below that they wrap and each line stays centred. */
.home-band .link-tiles {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 12px; max-width: 1100px; margin: 26px auto 0;
  padding: 0; list-style: none;
}
.home-band .link-tiles > li { margin: 0; }

/* These are the same control as the Popular Services pills, so they are built
   from the same spec rather than approximated: ink ground, white uppercase
   label, fully rounded. min-width gives all four one footprint — left to their
   labels they measured 191px to 246px. The decorative ↗ is dropped; it was
   applied to every tile regardless of whether the link actually left the site,
   so it signalled nothing. */
.home-band .link-tiles > li > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 262px;
  padding: 15px 18px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: .79rem;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  transition: transform .18s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.home-band .link-tiles > li > a::after { content: none; }
.home-band .link-tiles > li > a:hover {
  transform: translateY(-2px);
  background: var(--ink-3);
  color: #fff;
  box-shadow: var(--sh-2);
}

/* Placeholder portrait. Matches the real cards' square footprint exactly so a
   roster with one photo missing keeps its grid, and reads as deliberate rather
   than broken. */
.staff-pending {
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  border: 1px dashed var(--line-2);
  background:
    radial-gradient(80% 80% at 50% 30%, rgba(0,158,165,.10) 0%, rgba(0,158,165,0) 70%),
    var(--paper-3);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px; padding: 14px; text-align: center;
}
.staff-pending img { width: 56px; height: 56px; opacity: .92; }
.staff-pending span {
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 600; color: var(--muted); line-height: 1.3;
}

/* A short rule above each section heading. It reinforces the shared left edge
   and gives long pages a visible cadence, without indenting the heading and
   breaking the very alignment it is marking. */
/* Every section heading, not only direct children of .content — half the h2s on
   a page like Visitors sit inside a .split, and marking only the outer ones
   made the rule look like it appeared at random. */
.page-body .content h2::before {
  content: ""; display: block;
  width: 46px; height: 3px; border-radius: 2px;
  background: var(--grad-line);
  margin-bottom: 15px;
}

/* --- Top banner + navigation --------------------------------- */
/* A quiet sand strip rather than a saturated bar. It is a legal notice, not a
   headline, and it sits directly above the logo — colour here fought the mark. */
.banner {
  background: var(--paper-2);
  color: var(--ink-2);
  font-weight: 600;
  letter-spacing: 0.1em;
  font-size: 0.7rem;
  padding: 9px 16px;
  border-bottom: 1px solid var(--line);
}

nav.topnav {
  background: rgba(7,62,67,0.92);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  padding: 14px 24px;
  transition: padding .28s var(--ease), background .28s var(--ease),
              box-shadow .28s var(--ease);
}
/* Condensed state, set by the scroll observer in site.js. The nav gives back
   ~10px of vertical space once you are reading, and gains a shadow so it
   separates from the page instead of floating on it. */
nav.topnav.is-stuck {
  padding: 8px 24px;
  background: rgba(7,62,67,0.97);
  box-shadow: 0 6px 24px rgba(7,62,67,.28);
}

/* The real city wordmark replaces the placeholder seal that was drawn in SVG.
   It is white artwork, which is exactly right against the ink nav. Explicit
   width/height are set on the tag so the row cannot reflow once the image
   decodes — an unsized logo is the classic cause of nav shift on first paint. */
.nav-brand { display: inline-flex; align-items: center; gap: 0; }
.nav-logo {
  height: 40px; width: auto; display: block;
  transition: height .28s var(--ease);
}
nav.topnav.is-stuck .nav-logo { height: 31px; }
.footer-logo { height: 54px; width: auto; display: inline-block; opacity: .95; }

.nav-links > li > a {
  border-radius: 999px;
  font-weight: 500;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.nav-links > li > a:hover { background: rgba(255,255,255,0.10); color: var(--amber-lt); }
.nav-links > li > a.current {
  background: var(--grad-sun);
  color: #FFFFFF;
  font-weight: 600;
}
.submenu {
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);
  border: 1px solid var(--line);
  overflow: hidden;
  padding: 6px;
}
.submenu a { border-radius: var(--r-sm); }
.submenu a:hover { background: var(--paper-2); color: var(--clay); }

/* Reading-progress bar, injected by site.js so no page markup changes. */
.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: var(--grad-line);
  z-index: 200; pointer-events: none;
}

/* --- Hero ---------------------------------------------------- */
.hero-photo {
  min-height: 560px;
  padding: 108px 24px 96px;
}
.hero.compact.photo .hero-photo { min-height: 430px; padding: 84px 24px 72px; }

/* A three-stop scrim: ink at the edges, a warm core so the photography keeps
   its colour, and a deeper floor so the card below has something to sit on.
   Measured against the h1 box — see herocontrast.mjs — not eyeballed. */
.hero-photo::before {
  background:
    radial-gradient(120% 85% at 50% 40%, rgba(7,62,67,.14) 0%, rgba(7,62,67,.46) 68%, rgba(7,62,67,.70) 100%),
    linear-gradient(180deg, rgba(7,62,67,.44) 0%, rgba(7,62,67,.16) 45%, rgba(7,62,67,.66) 100%);
}
.hero-video .hero-photo::before {
  background:
    radial-gradient(120% 85% at 50% 40%, rgba(7,62,67,.18) 0%, rgba(7,62,67,.52) 68%, rgba(7,62,67,.74) 100%),
    linear-gradient(180deg, rgba(7,62,67,.48) 0%, rgba(7,62,67,.20) 45%, rgba(7,62,67,.70) 100%);
}
.hero-photo::after {
  /* A tighter, deeper pool sits directly behind the words. Concentrating the
     darkness where the text is lets the rest of the photograph stay bright,
     instead of flattening the whole frame to keep one headline readable. */
  background: radial-gradient(ellipse 60% 56% at center,
    rgba(4,40,44,.68) 0%, rgba(4,40,44,.38) 55%, rgba(4,40,44,0) 78%);
}

.hero-photo h1 {
  font-size: clamp(2.4rem, 6.2vw, 4.4rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  color: #fff;
  text-shadow: 0 2px 30px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.45);
}
.hero-photo .hero-label {
  display: inline-block;
  padding: 6px 16px;
  border-radius: 999px;
  /* This chip must DARKEN its backdrop, not lighten it. A white 12% wash over
     the hero video brightened whatever was behind the label, and pale amber on
     top of that measured 2.05:1 against the worst frame — the eyebrow is ~11px,
     so it needs 4.5:1. An ink wash puts the amber back on a dark ground. */
  background: rgba(7,62,67,.82);
  border: 1px solid rgba(143,215,211,.34);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--amber-lt);
  letter-spacing: .16em;
  font-size: .68rem;
  margin-bottom: 20px;
}
.hero-photo .hero-sub {
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  max-width: 720px;
  color: rgba(255,255,255,.94);
}
.hero-photo .divider {
  height: 3px; width: 76px; border-radius: 2px;
  background: var(--grad-sun);
  margin-top: 28px;
}

/* Entrance: the hero contents rise in once, in sequence. Purely additive —
   with reduced motion requested they simply appear (see the block at the end). */
.hero-photo .hero-label,
.hero-photo h1,
.hero-photo .hero-sub,
.hero-photo .divider,
.hero-photo .hero-credit {
  animation: rise .85s var(--ease) both;
}
.hero-photo h1          { animation-delay: .08s; }
.hero-photo .hero-sub   { animation-delay: .17s; }
.hero-photo .divider    { animation-delay: .25s; }
.hero-photo .hero-credit{ animation-delay: .32s; }

@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* --- Buttons ------------------------------------------------- */
.btn-primary, .btn-ghost {
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: .04em;
  transition: transform .18s var(--ease), box-shadow .22s var(--ease),
              background .22s var(--ease), color .22s var(--ease);
}
.btn-primary {
  background: var(--grad-sun);
  color: #FFFFFF;
  border: none;
  box-shadow: 0 4px 14px rgba(12,107,115,.34);
}
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(12,107,115,.44);
  background: var(--grad-sun);
  color: #FFFFFF;
}
.btn-ghost {
  border: 1.5px solid rgba(7,62,67,.22);
  color: var(--ink);
  background: transparent;
}
.btn-ghost:hover {
  transform: translateY(-2px);
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}

/* --- Feature card (homepage) --------------------------------- */
.feature-card {
  border-radius: var(--r-xl);
  box-shadow: var(--sh-3);
  border: 1px solid rgba(255,255,255,.6);
  padding: 52px 44px;
}
.feature-eyebrow { color: var(--clay); letter-spacing: .18em; font-weight: 600; }
.feature-card h2 { font-size: clamp(1.8rem, 3.4vw, 2.6rem); font-weight: 900; letter-spacing: -.025em; }

/* --- Section rhythm ------------------------------------------ */
.section-head .eyebrow {
  color: var(--clay);
  letter-spacing: .18em;
  font-weight: 600;
}
.section-head h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  font-weight: 900;
  letter-spacing: -.028em;
}
.section-head .sub { color: var(--muted); font-size: 1.04rem; }

/* Full-bleed tint behind alternating homepage bands.
   Done with a real full-width wrapper element, NOT a -50vw pseudo-element
   bleed: 100vw/-50vw include the scrollbar gutter, so the bleed is wider than
   the content box and pushes out a horizontal scrollbar. body's
   overflow-x:hidden hides the bar but the document still measures wider, which
   is exactly what sweep.mjs is there to catch. */
.band-tint { background: var(--paper-2); padding: 26px 0 34px; }
.band-tint > .section { margin-top: 34px; }

/* --- Department cards ---------------------------------------- */
/* Seven cards into a 4-wide grid leaves three on the last row, which CSS grid
   parks hard against the left edge with a card's worth of hole on the right.
   Flex wrapping centres the short row instead. Each card keeps a FIXED basis
   (flex-grow: 0) so the three do not stretch to fill the row -- the same
   stretch failure that auto-fill was chosen to avoid on .quicklinks. */
.dept-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
}
.dept-grid > .dept-card { flex: 0 1 100%; }
@media (min-width: 640px) {
  .dept-grid > .dept-card { flex: 0 1 calc((100% - 20px) / 2); }
}
@media (min-width: 1000px) {
  .dept-grid > .dept-card { flex: 0 1 calc((100% - 60px) / 4); }
}

/* Button rows: one shared min-width so adjacent calls to action are the same
   box. Without it the buttons are as wide as their labels, so "Residents" and
   "Visitors" rendered at visibly different sizes side by side. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.btn-row > .btn-primary,
.btn-row > .btn-ghost {
  min-width: 190px;
  justify-content: center;
}
.dept-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: 26px 24px 22px;
  position: relative;
  overflow: hidden;
  transition: transform .26s var(--ease), box-shadow .26s var(--ease),
              border-color .26s var(--ease);
}
/* The gradient hairline only pays out on hover, so a grid of eight cards
   stays calm until you engage with one. */
.dept-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--grad-sun);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .3s var(--ease);
}
.dept-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-3);
  border-color: transparent;
}
.dept-card:hover::before { transform: scaleX(1); }
.dept-icon {
  background: var(--grad-sun);
  border-radius: var(--r-md);
  box-shadow: 0 4px 12px rgba(12,107,115,.3);
  width: 46px; height: 46px;
}
.dept-icon svg { color: #FFFFFF; width: 24px; height: 24px; }
.dept-card h3 { font-size: 1.14rem; margin-top: 16px; }
.dept-card p  { color: var(--muted); font-size: .95rem; }
.dept-more {
  color: var(--clay); font-weight: 600; letter-spacing: .06em;
  display: inline-flex; align-items: center; gap: 6px;
}
.dept-card:hover .dept-more { gap: 11px; }
.dept-more { transition: gap .24s var(--ease); }

/* --- Quick links, doc lists, tiles ---------------------------
   These were solid dark pills. Four of them under a heading were the heaviest
   thing on the page and the first thing below the hero, so a page opened with
   a row of black lozenges and read as unfinished. They are the same family as
   the link tiles now -- a white card, an arrow, a lift on hover -- with a
   little more presence, because on most pages these are the primary actions. */
.quicklinks a {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 62px;
  padding: 16px 24px;
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-weight: 650;
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
  border: 1px solid var(--line);
  box-shadow: var(--sh-1);
  transition: transform .18s var(--ease), box-shadow .22s var(--ease),
              border-color .18s var(--ease);
}
.quicklinks a::after {
  content: "→";
  color: var(--clay);
  font-weight: 400;
  transition: transform .22s var(--ease);
}
.quicklinks a:hover {
  transform: translateY(-3px);
  background: var(--surface);
  color: var(--ink);
  border-color: var(--brand-teal);
  box-shadow: var(--sh-2);
}
.quicklinks a:hover::after { transform: translateX(4px); }

/* --- Closing call to action ----------------------------------
   A section whose whole job is "go and do this" was a paragraph and a button
   adrift in a band. As a teal panel it closes the page, and it is the one
   place the page uses the brand's dark ground, which the interior pages
   otherwise never touch. */
.cta-panel {
  grid-column: wide;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 28px 48px;
  background: var(--grad-ink);
  border-radius: var(--r-lg);
  padding: 38px 44px;
  box-shadow: var(--sh-2);
}
.cta-panel h3 { color: #FFFFFF; margin: 0 0 8px; }
.cta-panel p { color: rgba(255,255,255,.82); margin: 0; max-width: 60ch; }
.cta-panel .btn-row { margin: 0; }
.cta-panel .btn-primary {
  background: #FFFFFF;
  color: var(--ink);
  box-shadow: 0 6px 18px rgba(0,0,0,.22);
}
.cta-panel .btn-primary:hover { background: var(--paper); color: var(--ink); }
.content .cta-panel a.btn-primary { color: var(--ink); }

.doc-list a, .link-tiles a {
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  box-shadow: var(--sh-1);
  transition: transform .18s var(--ease), box-shadow .2s var(--ease),
              border-color .2s var(--ease);
}
.doc-list a:hover, .link-tiles a:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
  border-color: rgba(12,107,115,.45);
}
/* Component links opt out of the running-text underline. In a document list the
   whole tile is the control — it has a card border, a hover lift and a PDF
   badge — so underlining the label too turns 21 ordinances into a wall of
   orange rules. WCAG 1.4.1 is about telling a link apart from the prose around
   it; these have no prose around them. Underline returns on hover. */
.doc-list a, .link-tiles a, .quicklinks a, .chips a {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
}
.doc-list a:hover, .link-tiles a:hover {
  color: var(--clay);
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* Was `color: #fff`, which was correct while these were solid dark pills. They
   are white cards now, so white text made every label invisible -- the cards
   rendered as empty boxes with only an arrow in them. */
.quicklinks a, .quicklinks a:hover { color: var(--ink); }

.chips li {
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  box-shadow: var(--sh-1);
  transition: transform .18s var(--ease), border-color .18s var(--ease);
}
.chips li:hover { transform: translateY(-2px); border-color: var(--sunset); }

/* --- Cards, messages, call-outs ------------------------------ */
.card, .message {
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
  border: 1px solid var(--line);
}
.message { border-left: 4px solid transparent; border-image: var(--grad-sun) 1; }
.message > img { border-radius: var(--r-md); box-shadow: var(--sh-2); }

.call-out {
  border-radius: var(--r-md);
  border-left: 4px solid var(--amber);
  background: linear-gradient(90deg, rgba(242,169,59,.14), rgba(242,169,59,.05));
}

.accordion { border-radius: var(--r-md); border-color: var(--line); box-shadow: var(--sh-1); }
.accordion > summary { font-weight: 600; }

/* --- Portraits ----------------------------------------------- */
.staff-grid img, .photo-grid img {
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.staff-grid li:hover img, .photo-grid li:hover img {
  transform: translateY(-4px) scale(1.015);
  box-shadow: var(--sh-2);
}

/* --- Definition lists ---------------------------------------- */
.kv dt { color: var(--clay); }
.kv a  { color: var(--ink); text-decoration-color: rgba(7,62,67,.35); }

/* --- Facts ---------------------------------------------------- */
.facts > div {
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--sh-1);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease);
}
.facts > div:hover { transform: translateY(-4px); box-shadow: var(--sh-2); }

/* Source note under a stat grid. Small and muted so it reads as attribution
   rather than body copy -- these figures are the 2020 Census, and a public
   .gov page should say where a number came from. */
.content p.fine {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 10px;
  text-align: center;
}
.facts strong {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 900;
  background: var(--grad-sun);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* --- Info strip + footer ------------------------------------- */
.info-strip { background: var(--surface); border-top: 1px solid var(--line); }
.info-item .info-icon,
.info-item svg { color: var(--clay); }
.info-item h4 { font-family: 'Fraunces', Georgia, serif; font-weight: 700; }

/* The base/additions layers ask for 'Playfair Display' in 13 places, but this
   redesign loads only Fraunces + Inter -- Playfair has no @font-face and is not
   in the Google Fonts URL. Every rule still naming it therefore falls through to
   generic serif. Most were remapped above; .staff-card h4 was missed, which left
   all 12 council members and department heads on /government/ rendering in
   Times beside Fraunces headings. Remap rather than loading a third family:
   Fraunces is the chosen display face. */
.staff-card h4 { font-family: 'Fraunces', Georgia, serif; }

footer.site-footer, .site-footer {
  background: var(--grad-ink);
  position: relative;
}
.site-footer::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--grad-line);
}

/* --- Breadcrumbs --------------------------------------------- */
.crumbs { font-size: .84rem; color: var(--muted); padding-top: 22px; }
.crumbs a { color: var(--clay); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }

/* --- Scroll reveal ------------------------------------------- */
/* Applied by site.js to top-level blocks. The class is only added when the
   observer is available and motion is allowed, so content is never hidden
   from a browser that cannot animate it. */
.reveal { opacity: 0; transform: translateY(22px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}

/* --- Focus visibility ---------------------------------------- */
/* One consistent, high-contrast focus ring. The base sheet relied on the UA
   default, which disappears against the ink nav. */
a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --- Motion preferences -------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .hero-photo .hero-label,
  .hero-photo h1,
  .hero-photo .hero-sub,
  .hero-photo .divider,
  .hero-photo .hero-credit { animation: none; }
  .reveal, .reveal.is-in { opacity: 1; transform: none; transition: none; }
  .scroll-progress { display: none; }
  * { scroll-behavior: auto !important; }
}

/* --- Narrow screens ------------------------------------------ */
@media (max-width: 720px) {
  body { font-size: 16px; }
  .hero-photo { min-height: 420px; padding: 70px 20px 60px; }
  .hero.compact.photo .hero-photo { min-height: 330px; padding: 58px 20px 50px; }
  .feature-card { padding: 34px 24px; border-radius: var(--r-lg); }
  .section.band-tint { padding-top: 42px; padding-bottom: 42px; }
}

/* ============================================================
   Command-palette search
   ============================================================
   Reachable three ways so it is not a hidden power-user trick: the visible
   pill in the nav, Cmd/Ctrl-K, and "/". The nav pill is what makes it
   discoverable — a keyboard-only shortcut would be invisible to the residents
   this mostly serves. */
/* A plain round icon button, pinned to the right of the menu. It was a labelled
   pill, which cost enough width to push the whole nav onto a second row. The
   title attribute keeps the "/" shortcut discoverable without spending space. */
.nav-search {
  flex: none;
  width: 38px; height: 38px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.24);
  background: rgba(255,255,255,.08);
  color: rgba(255,255,255,.88);
  cursor: pointer;
  transition: background .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), transform .18s var(--ease);
}
.nav-search:hover {
  background: rgba(255,255,255,.18); color: #fff;
  border-color: rgba(255,255,255,.45); transform: scale(1.06);
}
.nav-search svg { width: 17px; height: 17px; flex: none; }
.cmdk { position: fixed; inset: 0; z-index: 300; display: grid; place-items: start center; padding: 11vh 16px 16px; }
.cmdk[hidden] { display: none; }
.cmdk-backdrop {
  position: absolute; inset: 0;
  background: rgba(8,14,28,.58);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  animation: cmdk-fade .18s var(--ease) both;
}
.cmdk-panel {
  position: relative; width: min(700px, 100%);
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); overflow: hidden;
  border: 1px solid rgba(255,255,255,.6);
  animation: cmdk-pop .22s var(--ease) both;
}
.cmdk-field { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--line); }
.cmdk-field > svg { width: 20px; height: 20px; color: var(--muted); flex: none; }
.cmdk-field input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 1.06rem; color: var(--text);
}
.cmdk-field input::-webkit-search-cancel-button { display: none; }
.cmdk-esc {
  flex: none; font: inherit; font-size: .7rem; cursor: pointer;
  padding: 3px 9px; border-radius: 6px; color: var(--muted);
  border: 1px solid var(--line-2); background: var(--paper);
}
.cmdk-esc:hover { color: var(--ink); border-color: var(--ink); }
.cmdk-count {
  padding: 11px 18px 5px; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .14em; color: var(--muted);
}
.cmdk-list { list-style: none; margin: 0; padding: 0 8px 8px; max-height: 50vh; overflow-y: auto; }
.cmdk-item a {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--r-sm);
  text-decoration: none; color: var(--text);
}
.cmdk-item.is-active a { background: var(--paper-2); }
.cmdk-kind {
  flex: none; font-size: .58rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .1em;
  padding: 3px 7px; border-radius: 5px; color: #FFFFFF;
}
.cmdk-kind-page    { background: var(--amber); }
.cmdk-kind-section { background: #CFE3DF; color: #123A34; }
.cmdk-kind-doc     { background: #F3D9CF; color: #6B2410; }
/* Services are actions, not reading - given the brand teal so they read
   as the primary thing to click when someone searches "bill". */
.cmdk-kind-service { background: #0A555C; color: #FFFFFF; }
.cmdk-t { flex: 1; min-width: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-s { flex: none; max-width: 34%; color: var(--muted); font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-empty { padding: 26px 18px 30px; color: var(--muted); text-align: center; font-size: .92rem; }
.cmdk-foot {
  display: flex; gap: 18px; flex-wrap: wrap;
  padding: 10px 18px; border-top: 1px solid var(--line);
  font-size: .7rem; color: var(--muted); background: var(--paper);
}
.cmdk-foot kbd {
  font: inherit; font-size: .68rem; padding: 1px 5px; margin-right: 3px;
  border: 1px solid var(--line-2); border-bottom-width: 2px;
  border-radius: 4px; background: var(--surface);
}
body.cmdk-open { overflow: hidden; }

@keyframes cmdk-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cmdk-pop  { from { opacity: 0; transform: translateY(-8px) scale(.985); } to { opacity: 1; transform: none; } }

@media (max-width: 720px) {
  .cmdk { padding-top: 6vh; }
  .cmdk-s { display: none; }
}

/* ============================================================
   Heart labyrinth panel
   ============================================================
   The only heart-shaped labyrinth in the world is Tonkawa's, and it is the
   single most distinctive thing the city has. It is drawn line by line as it
   scrolls into view rather than shown as a photograph. */
/* The panel is a top-level section, so it is already full width — it needs a
   background, not a viewport-unit bleed. */
/* Butt the dark panel straight onto the tinted band above it — a strip of
   paper between two full-width bands reads as a mistake, not as breathing room. */
.band-tint + .labyrinth-panel { margin-top: 0; }

.labyrinth-panel {
  position: relative;
  margin: 78px 0 0;
  padding: 78px 24px 82px;
  color: var(--text);
  /* A soft teal wash, not a black slab. This is the one moment on the page
     that is purely about the place rather than about services, so it wants to
     feel open — a dark band here just made the page feel heavy. */
  background:
    radial-gradient(120% 90% at 78% 50%, rgba(0,158,165,.10) 0%, rgba(0,158,165,0) 62%),
    var(--paper-3);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.labyrinth-inner {
  position: relative; z-index: 1;
  max-width: var(--page); margin-inline: auto;
  display: grid; grid-template-columns: 1fr 0.85fr;
  gap: 54px; align-items: center;
}
.labyrinth-copy .eyebrow {
  color: var(--clay); letter-spacing: .18em;
  font-size: .72rem; font-weight: 600; text-transform: uppercase;
}
.labyrinth-copy h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.9rem, 3.6vw, 2.8rem);
  font-weight: 900; letter-spacing: -.028em;
  color: var(--ink); margin: 14px 0 16px;
}
.labyrinth-copy p { color: var(--text); font-size: 1.06rem; line-height: 1.75; max-width: 50ch; }
.labyrinth-copy .btn-ghost {
  margin-top: 28px; border-color: var(--ink-3); color: var(--ink-2);
}
.labyrinth-copy .btn-ghost:hover { background: var(--ink-2); color: #fff; border-color: var(--ink-2); }
.labyrinth { display: grid; place-items: center; }
.labyrinth svg { width: min(100%, 380px); height: auto; overflow: visible; }
.labyrinth svg path {
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 1.7;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.labyrinth svg path:nth-child(even) { stroke: var(--brand-teal); }
.labyrinth svg path:nth-child(n+5)  { stroke: var(--brand-orange); }

@media (max-width: 900px) {
  .labyrinth-inner { grid-template-columns: 1fr; gap: 34px; }
  .labyrinth { order: -1; }
  .labyrinth svg { width: min(100%, 300px); }
  .labyrinth-panel { padding: 54px 20px 58px; margin-top: 54px; }
}

/* ============================================================
   Careers
   ============================================================ */
.job-tools {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 20px;
  margin: 30px 0 14px; padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.job-filter { display: flex; flex-wrap: wrap; gap: 8px; }
.job-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: .86rem; font-weight: 500;
  color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--line-2);
  transition: background .16s var(--ease), color .16s var(--ease),
              border-color .16s var(--ease), transform .16s var(--ease);
}
.job-chip:hover { border-color: var(--ink-3); transform: translateY(-1px); }
.job-chip.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }
.job-chip-n {
  font-size: .74rem; font-weight: 600; line-height: 1;
  padding: 3px 7px; border-radius: 999px;
  background: var(--paper-3); color: var(--ink-2);
}
.job-chip.is-on .job-chip-n { background: rgba(255,255,255,.22); color: #fff; }

.job-sort { display: inline-flex; align-items: center; gap: 8px; font-size: .86rem; color: var(--muted); }
.job-sort select {
  font: inherit; font-size: .86rem; color: var(--ink-2);
  padding: 8px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface);
}
.job-count { font-size: .84rem; color: var(--muted); margin: 0 0 22px; }

.job-list { display: grid; gap: 16px; }
.job {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--ink-3);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: 24px 26px;
  transition: box-shadow .22s var(--ease), transform .22s var(--ease);
}
.job:hover { box-shadow: var(--sh-2); transform: translateY(-2px); }
.job[hidden] { display: none; }
.job-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.job-dept, .job-type {
  font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 5px;
}
.job-dept { background: var(--paper-3); color: var(--ink-2); }
.job-type { background: rgba(168,65,15,.10); color: var(--clay); }
.job h2 { margin: 0 0 8px; font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
/* The accent rule belongs to page-level headings, not to every job card. */
.job h2::before { content: none; }
.job-summary { margin: 0; color: var(--text); max-width: 62ch; }

.job-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px;
  margin-top: 18px;
}
.job-actions .btn-primary { flex: none; }
.job-detail { flex: 1 1 auto; min-width: 220px; }
.job-detail > summary {
  cursor: pointer; list-style: none; font-size: .9rem; font-weight: 600;
  color: var(--link); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: rgba(10,85,92,.35);
}
.job-detail > summary::-webkit-details-marker { display: none; }
.job-detail[open] > summary { margin-bottom: 12px; }
.job-detail .acc-body { font-size: .96rem; }
.job-detail .acc-body ul { margin: 8px 0 14px 20px; }
.job-detail .acc-body li { margin-bottom: 5px; }
.job-deliver {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--r-sm);
  background: var(--paper-3); font-size: .92rem;
}
.job-empty { padding: 26px; text-align: center; color: var(--muted); }

/* ============================================================
   Application form
   ============================================================ */
.apply-form { max-width: 860px; margin: 26px 0 0; }
.form-block {
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 20px 22px 22px; margin: 0 0 16px; background: var(--surface);
}
.form-block-lead { border-color: var(--ink-3); box-shadow: var(--sh-1); }
.form-block > legend {
  padding: 0 8px; font-family: 'Fraunces', Georgia, serif;
  font-weight: 700; font-size: 1.02rem; color: var(--ink);
}
.form-heading {
  font-family: 'Fraunces', Georgia, serif; font-weight: 700;
  font-size: 1.15rem; color: var(--ink); margin: 30px 0 12px;
}
.form-grid {
  display: grid; gap: 14px 18px;
  /* min() so the track can never be wider than the container — at 360px the
     fieldset padding leaves less than the floor, and a bare minmax() overflows. */
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
}
.form-wide { grid-column: 1 / -1; }
/* Every label in the form, not just those inside .form-grid — the "Anything
   else" label sits directly in its fieldset, so a .form-grid-only rule left it
   inline and the textarea rendered beside the question instead of under it. */
.apply-form label,
.contact-form label {
  display: flex; flex-direction: column; gap: 6px;
  font-size: .82rem; font-weight: 600; color: var(--ink-2);
}
.apply-form textarea, .contact-form textarea { width: 100%; resize: vertical; min-height: 120px; }
.apply-form input, .apply-form select, .apply-form textarea,
.contact-form input, .contact-form select, .contact-form textarea {
  font: inherit; font-size: .95rem; font-weight: 400; color: var(--text);
  padding: 10px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--paper);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.apply-form input:focus, .apply-form select:focus, .apply-form textarea:focus,
.contact-form input:focus, .contact-form select:focus, .contact-form textarea:focus {
  outline: none; border-color: var(--ink-3);
  box-shadow: 0 0 0 3px rgba(12,107,115,.16);
}
.apply-form .is-invalid, .contact-form .is-invalid { border-color: var(--clay); background: rgba(168,65,15,.05); }
/* The position that came from the Apply Now button, marked so it is obvious it
   was filled in for you rather than left blank. */
.is-prefilled select { border-color: var(--ink-3); background: var(--paper-3); font-weight: 600; }
.form-note { font-size: .9rem; color: var(--muted); margin: 6px 0 14px; }
.form-error {
  margin: 4px 0 14px; padding: 12px 14px; border-radius: var(--r-sm);
  background: rgba(168,65,15,.09); color: var(--clay); font-weight: 600; font-size: .92rem;
}
.form-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.apply-alt { margin-top: 46px; }
.print-head { display: none; }

@media (max-width: 720px) {
  .job { padding: 20px 18px; }
  .job-tools { gap: 12px; }
  .job-sort { width: 100%; }
}

/* ============================================================
   Print — the filled application
   ============================================================
   The form IS the printable document: browsers print an input's current value,
   so there is no second render to keep in sync. Everything that is not the
   application is dropped. */
@media print {
  .banner, nav.topnav, footer, .info-strip, .hero, .crumbs,
  .form-actions, .apply-alt, .scroll-progress, .cmdk, .job-tools { display: none !important; }
  body { background: #fff; color: #000; font-size: 10.5pt; }
  .page-body, .content, .apply-form { max-width: none; width: auto; padding: 0; margin: 0; }
  .print-head {
    display: flex; flex-direction: column; gap: 2px;
    border-bottom: 2px solid #000; padding-bottom: 8px; margin-bottom: 14px;
  }
  .print-head strong { font-size: 13pt; }
  .print-head span { font-size: 9pt; }
  .form-block { break-inside: avoid; page-break-inside: avoid; border: 1px solid #999; box-shadow: none; }
  .form-block > legend { font-size: 11pt; }
  .apply-form input, .apply-form select, .apply-form textarea,
.contact-form input, .contact-form select, .contact-form textarea {
    border: 0; border-bottom: 1px solid #999; border-radius: 0;
    background: transparent; padding: 2px 0; color: #000;
  }
  .form-note { color: #000; }
  .reveal, .reveal.is-in { opacity: 1 !important; transform: none !important; }
}

/* Buttons inside .content are still <a>, so `.content a` (0,2,0) outranks
   `.btn-primary` (0,1,0) and was repainting the label link-teal on a teal pill
   — invisible — and underlining it. Buttons opt out explicitly. */
.content a.btn-primary,
.content a.btn-ghost,
.content a.btn-primary:hover,
.content a.btn-ghost:hover { text-decoration: none; }
.content a.btn-primary, .content a.btn-primary:hover { color: #fff; }
.content a.btn-ghost { color: var(--ink); }
.content a.btn-ghost:hover { color: #fff; }

/* Same problem one level down: the section-heading accent rule is
   `.page-body .content h2::before` (0,2,1), which beat `.job h2::before` and
   drew a rule above every job title. */
.page-body .content .job h2::before { content: none; }

/* Employment-history and reference blocks pair better in two columns: employer
   beside job title, then From beside To. At three columns the date fields split
   across rows and left a column of dead space in every block. */
.form-block-pair .form-grid { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }

@media print {
  /* The picker button is chrome, not part of the document. */
  input::-webkit-calendar-picker-indicator { display: none; }
}

/* Grid and flex items default to min-width:auto, so a control is never allowed
   to be narrower than its own content. The position <select> carries option
   text like "E-911 Part-Time Dispatch Operator — Police Department", which made
   it 462px intrinsically and forced the whole grid track — and the page — wider
   than a 390px phone. Let the controls shrink and truncate instead. */
.form-grid > *,
.apply-form label,
.contact-form label { min-width: 0; }
.apply-form input,
.apply-form select,
.apply-form textarea,
.contact-form input,
.contact-form select,
.contact-form textarea { min-width: 0; max-width: 100%; }

/* ============================================================
   Contact form
   ============================================================ */
.contact-form { max-width: 760px; margin: 22px 0 8px; }
.form-opt { font-weight: 400; color: var(--muted); }

/* The honeypot must be reachable by a bot parsing the DOM but invisible and
   unfocusable for everyone else — so it is moved off-screen rather than
   display:none, which some bots skip. */
.hp {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

.form-ok {
  margin: 4px 0 14px; padding: 14px 16px; border-radius: var(--r-sm);
  background: var(--paper-3); color: var(--ink);
  border-left: 4px solid var(--ink-3);
  font-weight: 600; font-size: .95rem;
}

/* ============================================================
   Contact — details beside the form
   ============================================================
   Two columns that share the page's single left edge: the left one keeps its
   start, the right one is a second column rather than a second alignment. The
   form column is narrower because .kv rows (label + phone + street) need the
   width more than a stack of inputs does. Collapses to one column early — a
   two-column form on a tablet is worse than a long one. */
.contact-split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 30px 52px;
  align-items: start;
  margin-top: 8px;
}
.contact-split > .contact-col > *:first-child { margin-top: 0; }
.contact-col-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: 26px 28px 28px;
  position: sticky;
  top: 88px;
}
.contact-col-form .contact-form { max-width: none; margin-top: 16px; }
/* Inside a single column the two-up grid is too tight — stack the fields. */
.contact-col-form .form-grid { grid-template-columns: 1fr; gap: 12px; }

@media (max-width: 1000px) {
  .contact-split { grid-template-columns: 1fr; gap: 28px; }
  .contact-col-form { position: static; }
}

/* Quick-link pills pack to their labels instead of sitting in fixed grid
   tracks. In the narrower text column the auto-fill grid left four pills as
   3 + 1, with the orphan alone on its own row. `flex: 0 0 auto` keeps a lone
   pill from stretching to fill the row — the same failure the grid's auto-fill
   (rather than auto-fit) was chosen to avoid. */
.content > .quicklinks {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  max-width: var(--wide);
}
.content > .quicklinks > a { flex: 0 0 auto; }

/* Landing-style bands hold card grids, not prose, so they take the wider
   measure — at the text width the seven department cards were squeezed to
   ~190px and every title broke over three lines. The .content inside a band
   keeps the text measure and stays centred on the same axis. */
.section { max-width: var(--wide); }

/* The 780px figure cap existed to stop a photo dominating a 1280px container.
   The text column is now narrower than that cap, so all it did was inset
   figures 6px from every other block — a single stray edge on the page. */
.content > figure { max-width: none; }

/* Full-width bands hold a panel or a row of controls, not prose, so they use
   the wider measure. Left at the text width the labyrinth panel squeezed its
   illustration and the links row broke four pills into 3 + 1. */
.home-band-inner,
.labyrinth-inner { max-width: var(--wide); }
.home-band .link-tiles > li > a { min-width: 244px; }

/* The seven service cards (home page and Government) sat in the 1040px band, which at 1920
   left a 992px strip of 233px cards stranded in dead space. This band is a card
   grid, not prose, so it opens to the full page width.

   Only the GRID widens. .section-head keeps the reading measure and stays
   centred on the same axis, so this does not introduce a second text alignment
   -- the fault that took three attempts to settle. No 100vw/-50vw trick either:
   viewport units include the scrollbar gutter and overflow the document. The
   band is simply uncapped inside .band-tint, which is already full width. */
.dept-band {
  max-width: none;
  padding-inline: clamp(20px, 3.5vw, 72px);
}
.dept-band > .section-head {
  max-width: var(--page);
  margin-inline: auto;
}

/* ============================================================
   Mobile navigation — hamburger
   ============================================================
   The list is last in the DOM so that on a phone the panel follows the button
   that opens it in tab order. `order` restores the desktop arrangement. */
.nav-brand  { order: 1; }
.nav-links  { order: 2; }
.nav-search { order: 3; }
.nav-toggle { order: 4; display: none; }

.nav-toggle {
  flex: none;
  width: 38px; height: 38px; padding: 0;
  align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.24);
  background: rgba(255,255,255,.08);
  color: #fff;
  cursor: pointer;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.nav-toggle:hover { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.45); }
.nav-toggle-box { position: relative; display: block; width: 17px; height: 12px; }
.nav-toggle-bar,
.nav-toggle-bar::before,
.nav-toggle-bar::after {
  position: absolute; left: 0; right: 0; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: transform .26s var(--ease), background-color .18s var(--ease);
}
.nav-toggle-bar { top: 5px; }
.nav-toggle-bar::before { content: ""; top: -5px; }
.nav-toggle-bar::after  { content: ""; top:  5px; }
/* Bars fold into a cross while the panel is open. */
nav.topnav.is-open .nav-toggle-bar { background: transparent; }
nav.topnav.is-open .nav-toggle-bar::before { transform: translateY(5px) rotate(45deg); }
nav.topnav.is-open .nav-toggle-bar::after  { transform: translateY(-5px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .nav-inner {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 10px;
  }
  /* Brand hard left, search and hamburger hard right. */
  .nav-brand { margin-right: auto; }
  .nav-search { order: 3; }
  .nav-toggle { order: 4; }

  /* The panel occupies the full width beneath the bar and is collapsed by
     height, not display:none, so it can animate and so its links stay in the
     document for assistive tech to find. */
  .nav-links {
    order: 5;
    flex-basis: 100%;
    width: 100%;
    display: block;
    margin: 0; padding: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height .3s var(--ease);
  }
  nav.topnav.is-open .nav-links {
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    margin-top: 6px;
  }

  .nav-links > li { display: block; width: 100%; }
  .nav-links > li > a {
    display: block;
    padding: 13px 6px;
    font-size: .95rem;
    border-radius: 0;
    border-bottom: 1px solid rgba(255,255,255,.10);
  }
  .nav-links > li:last-child > a { border-bottom: 0; }
  .nav-links > li > a.current { background: var(--ink-3); color: #fff; border-radius: 8px; }

  /* Services becomes a tap-to-expand group. Hover cannot open a submenu on a
     touch screen, so the base sheet's :hover/:focus-within rules are replaced
     with an explicit .is-open that site.js sets. */
  .nav-links .has-sub > a { display: flex; align-items: center; justify-content: space-between; }
  .nav-links .has-sub > a::after {
    content: ""; width: 8px; height: 8px; margin-left: 10px;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .24s var(--ease);
  }
  .nav-links .has-sub.is-open > a::after { transform: rotate(-135deg) translate(-2px, -2px); }
  .nav-links .has-sub:hover .submenu,
  .nav-links .has-sub:focus-within .submenu { display: none; }
  .nav-links .has-sub.is-open .submenu { display: block; }
  .nav-links .submenu {
    position: static; opacity: 1; visibility: visible; transform: none;
    display: none; box-shadow: none; border: 0; border-radius: 0;
    background: rgba(0,0,0,.20);
    padding: 4px 0; margin: 0; min-width: 0; width: 100%;
  }
  .nav-links .submenu a {
    display: block; padding: 11px 6px 11px 22px;
    color: rgba(255,255,255,.86); border-radius: 0; font-size: .92rem;
  }
  .nav-links .submenu a:hover { background: rgba(255,255,255,.08); color: #fff; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-links, .nav-toggle-bar,
  .nav-toggle-bar::before, .nav-toggle-bar::after { transition: none; }
}
