/*
Theme Name: Townsy
Theme URI: https://townsy.co
Author: BlueTrunk
Author URI: https://bluetrunk.co
Description: A custom Bootstrap 5 municipal theme powered by ACF. No page builder required.
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
License: Proprietary
Text Domain: townsy
*/

/* =========================================================
   PUBLIC SANS — Self-hosted font (bundled with theme)
   Full weight range with italics. No external CDN required.
   font-display: swap prevents invisible text during load.
   ========================================================= */

@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Thin.woff2') format('woff2'); font-weight: 100; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-ThinItalic.woff2') format('woff2'); font-weight: 100; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-ExtraLight.woff2') format('woff2'); font-weight: 200; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-ExtraLightItalic.woff2') format('woff2'); font-weight: 200; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Light.woff2') format('woff2'); font-weight: 300; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-LightItalic.woff2') format('woff2'); font-weight: 300; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Italic.woff2') format('woff2'); font-weight: 400; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Medium.woff2') format('woff2'); font-weight: 500; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-MediumItalic.woff2') format('woff2'); font-weight: 500; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-SemiBold.woff2') format('woff2'); font-weight: 600; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-SemiBoldItalic.woff2') format('woff2'); font-weight: 600; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-BoldItalic.woff2') format('woff2'); font-weight: 700; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-ExtraBold.woff2') format('woff2'); font-weight: 800; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-ExtraBoldItalic.woff2') format('woff2'); font-weight: 800; font-style: italic;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-Black.woff2') format('woff2'); font-weight: 900; font-style: normal;  font-display: swap; }
@font-face { font-family: 'Public Sans'; src: url('assets/fonts/publicsans/PublicSans-BlackItalic.woff2') format('woff2'); font-weight: 900; font-style: italic;  font-display: swap; }

/* =========================================================
   TOWNSY THEME — Global Custom Properties
   ========================================================= */

:root {
    --townsy-primary:        #1a3a5c;   /* deep navy — override per client */
    --townsy-primary-light:  #2a5a8c;
    --townsy-secondary:      #e8a020;   /* gold accent (decorative use only — fails contrast on white) */
    --townsy-label-color:    #7a5500;   /* accessible dark amber for eyebrow/label text (6.5:1 on white) */
    --townsy-text:           #2d2d2d;
    --townsy-text-muted:     #5a6268;   /* darkened from #6c757d to pass WCAG AA 4.5:1 on white */
    --townsy-bg-light:       #f4f6f8;
    --townsy-border:         #dee2e6;
    --townsy-white:          #ffffff;

    /* Height of the sticky site header, used to offset other sticky
       elements. townsy.js keeps it equal to the rendered header, which
       varies with the logo and whether the town name wraps; this is the
       fallback before the script runs. */
    --townsy-header-height:  84px;
    --townsy-radius:         6px;
    --townsy-shadow:         0 2px 12px rgba(0,0,0,.08);
    --townsy-shadow-md:      0 4px 24px rgba(0,0,0,.12);

    /* Breadcrumb link color for light-background contexts.
       Override this per-client via ACF inline style injection
       or a child theme :root block. */
    --townsy-breadcrumb-link-color:       var(--townsy-primary);
    --townsy-breadcrumb-link-color-hover: var(--townsy-primary-light);

    /* Typography — Public Sans is bundled in assets/fonts/publicsans/.
       Override in a child theme :root block to change fonts site-wide. */
    --townsy-font-body:    'Public Sans', system-ui, -apple-system, sans-serif;
    --townsy-font-heading: 'Public Sans', system-ui, -apple-system, sans-serif;

    /* Secondary colour variants */
    --townsy-secondary-dark:       #d4911a;   /* darkened secondary for hover states */
    --townsy-secondary-focus-glow: rgba(232, 160, 32, .25); /* focus ring ambient glow */

    /* Focus indicator (WCAG 2.2 SC 1.4.11 — Non-text Contrast).
       Deliberately two-tone. --townsy-focus-ring carries the contrast on light
       backgrounds; --townsy-focus-ring-inverse carries it on dark ones (footer,
       skip link, announcement bar). Because the two rings also contrast against
       each other, the indicator stays visible on any background — which is why
       the theme needs no per-section focus overrides.

       --townsy-focus-ring must reach 3:1 against BOTH white and
       --townsy-bg-light. Do not substitute --townsy-secondary here: it is
       decorative and fails that threshold in most palettes. */
    --townsy-focus-ring:           #a86c00;   /* 4.37:1 on white, 4.03:1 on bg-light */
    --townsy-focus-ring-inverse:   #ffffff;

    /* Vertical space a page section puts above and below its content, so every
       boundary between sections is two of these. Matches Bootstrap's py-5,
       which is what the templates use. See the SECTION RHYTHM block below. */
    --townsy-section-space:        3rem;

    /* Footer text — override when using a light-coloured footer */
    --townsy-footer-text:     rgba(255, 255, 255, .82);
    --townsy-footer-text-dim: rgba(255, 255, 255, .75);

    /* Typography scale — based on government.nl / USWDS proportions.
       16px browser default base. rem values scale with user preferences. */
    --townsy-text-sm:            0.875rem;  /* 14px — captions, labels      */
    --townsy-text-base:          1rem;      /* 16px — body default           */
    --townsy-text-lg:            1.125rem;  /* 18px — slightly larger body   */
    --townsy-text-xl:            1.25rem;   /* 20px — lead / intro paragraph */

    --townsy-h6-size:            0.875rem;  /* 14px */
    --townsy-h5-size:            1rem;      /* 16px */
    --townsy-h4-size:            1.125rem;  /* 18px */
    --townsy-h3-size:            1.375rem;  /* 22px */
    --townsy-h2-size:            1.75rem;   /* 28px */
    --townsy-h1-size:            2.25rem;   /* 36px */

    --townsy-line-height-body:    1.625;    /* spacious, accessibility-friendly */
    --townsy-line-height-heading: 1.2;      /* tighter for display sizes        */
}

/* =========================================================
   BASE
   ========================================================= */

body {
    font-family: var(--townsy-font-body);
    font-size: var(--townsy-text-base);
    color: var(--townsy-text);
    background: var(--townsy-white);
    line-height: var(--townsy-line-height-body);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--townsy-font-heading);
    line-height: var(--townsy-line-height-heading);
}

h1 { font-size: var(--townsy-h1-size); }
h2 { font-size: var(--townsy-h2-size); }
h3 { font-size: var(--townsy-h3-size); }
h4 { font-size: var(--townsy-h4-size); }
h5 { font-size: var(--townsy-h5-size); }
h6 { font-size: var(--townsy-h6-size); }

a {
    color: var(--townsy-primary);
    text-decoration: none;
}
a:hover {
    color: var(--townsy-primary-light);
    text-decoration: underline;
}

img { max-width: 100%; height: auto; }

/* =========================================================
   SECTION RHYTHM

   The vertical space a page section puts above and below its content. Every
   boundary between sections is therefore two of these, one from each side.

   The templates express this with Bootstrap's py-5 utility, in 36 places
   across 25 files. Re-pointing the utility inside <main> gives the rhythm a
   single source of truth without migrating all 36, and means a component that
   has to line up with it — the news panel — can reference the variable rather
   than repeat a number that would silently drift the next time this changes.

   Bootstrap's utilities are declared !important, so matching them needs the
   same. The selectors are scoped to <main> so the utility keeps its normal
   Bootstrap meaning everywhere else, including the admin bar and plugins.

   The default is 3rem, exactly what py-5 already was: nothing moves unless a
   town opts in by overriding the variable.
   ========================================================= */

main.py-5,
main .py-5 {
    padding-top:    var(--townsy-section-space, 3rem) !important;
    padding-bottom: var(--townsy-section-space, 3rem) !important;
}

/* =========================================================
   ANNOUNCEMENT BAR
   ========================================================= */

.announcement-bar {
    background: var(--townsy-primary);
    color: var(--townsy-white);
    font-size: .85rem;
    padding: .4rem 0;
}
.announce-bar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0 1.25rem;
    min-height: 2rem;
    max-width: 1320px;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
}


/* ---------------------------------------------------------
   Alert banner — Warning and Emergency states
   Replaces the normal announcement bar. Colors chosen for
   >7:1 contrast ratio with white text (WCAG AA+).
   --------------------------------------------------------- */

/* Warning — dark amber */
.announcement-bar--warning {
    background: #92400e;   /* 7.2:1 contrast with #fff */
    color: #fff;
}

/* Emergency — dark red */
.announcement-bar--emergency {
    background: #991b1b;   /* 7.4:1 contrast with #fff */
    color: #fff;
}

/* Alert mode inner layout — centered, no left/right cols */
.alert-banner-mode {
    justify-content: center;
}
.alert-banner-content {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: .25rem .75rem;
    font-weight: 600;
    font-size: var(--townsy-text-base);
}
.alert-banner-link {
    color: #fff;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}
.alert-banner-link:hover {
    color: rgba(255,255,255,.85);
    text-decoration: underline;
}
.alert-banner-link:focus-visible {
    outline: 3px solid var(--townsy-focus-ring-inverse);
    outline-offset: 2px;
    border-radius: 2px;
}

/* ---------------------------------------------------------
   The three columns and the page width

   Every column here sets white-space: nowrap, and a flex item's
   automatic minimum size is its content — so without min-width: 0
   none of them can shrink below the full width of whatever text a
   town happens to enter. Three unshrinkable columns on a phone add
   up to more than the viewport, and the overflow lands on the
   document: the page scrolls sideways into empty space.

   min-width: 0 lets them shrink, and overflow: hidden keeps the
   nowrap text from painting past the box once they do (visible
   overflow would scroll the page just the same). The announcement
   text is the variable-length one, so the centre column is the one
   allowed to grow and the one that truncates first.
   --------------------------------------------------------- */

/* Left — weather (equal share, left-aligned) */
.announce-bar-left {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
}
.announce-weather {
    opacity: .92;
}

/* Center — cycling announcements (true center) */
.announce-bar-center {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-width: 0;
    text-align: center;
}
.announce-cycler {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.announce-item {
    display: none;
    white-space: nowrap;
}
.announce-item.is-active {
    display: inline;
    animation: announce-jiggle .55s ease both;
}
@keyframes announce-jiggle {
    0%   { transform: translateX(0);    opacity: 0; }
    15%  { transform: translateX(-5px); opacity: 1; }
    30%  { transform: translateX(4px); }
    45%  { transform: translateX(-3px); }
    60%  { transform: translateX(2px); }
    75%  { transform: translateX(-1px); }
    100% { transform: translateX(0);    opacity: 1; }
}

/* Right — news link (equal share, right-aligned) */
.announce-bar-right {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: right;
}
.announce-blog-link {
    color: var(--townsy-white);
    font-weight: 700;
    text-decoration: none;
    letter-spacing: .02em;
}
.announce-blog-link:hover {
    text-decoration: underline;
    color: var(--townsy-white);
    opacity: .85;
}

/* ---------------------------------------------------------
   Phones — stack instead of squeezing

   Three columns in ~305px cannot all keep their text. Side by
   side, the default "News & Updates" needs 156px of the ~270px
   available, and whichever column is made to give way ends up
   truncated: either the announcement shows a few words, or the
   link reads "News & Upd…". A cut-off nav label is the worse of
   the two — a truncated sentence still carries some meaning,
   while a truncated label just looks broken.

   So the bar becomes two rows: the announcement, then the link.
   The weather is the one item here that is purely ambient, and
   a third row for it would cost more than it is worth, so it is
   the only thing dropped. Nothing else is hidden — the link is
   navigation, and a town is not required to have put News in its
   menu, so hiding it could make that page unreachable on a phone.
   --------------------------------------------------------- */
@media (max-width: 575.98px) {
    .announce-bar-inner {
        flex-wrap: wrap;
        justify-content: center;
        gap: .15rem .75rem;
        padding: .15rem 1rem;
    }
    .announce-bar-left {
        display: none;
    }
    .announce-bar-center {
        flex: 1 1 100%;
        order: 1;
    }
    .announce-bar-right {
        flex: 1 1 100%;
        order: 2;
        text-align: center;
    }
}

/* =========================================================
   HEADER / NAVBAR
   ========================================================= */

.site-header {
    background: var(--townsy-white);
    border-bottom: 3px solid var(--townsy-secondary);
    box-shadow: var(--townsy-shadow);
    position: sticky;
    top: 0;
    z-index: 1030;
}

.site-header .navbar-brand img {
    max-height: 54px;
    width: auto;
    /* aria-hidden="true" in markup — decorative only, text carries the meaning */
}

.site-header .navbar-brand .site-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.site-header .navbar-brand .site-title {
    font-size: var(--townsy-text-xl);   /* 1.25rem / 20px */
    font-weight: 700;
    color: var(--townsy-primary);
    line-height: var(--townsy-line-height-heading);
}

.site-header .navbar-brand .site-tagline {
    font-size: var(--townsy-text-sm);   /* 0.875rem / 14px — meets WCAG minimum */
    color: var(--townsy-text-muted);
    display: block;
}

/* Nav links */
.site-header .nav-link {
    color: var(--townsy-primary) !important;
    font-weight: 600;
    font-size: .92rem;
    padding: .5rem .85rem !important;
    border-radius: var(--townsy-radius);
    transition: background .15s, color .15s;
}
.site-header .nav-link:hover,
.site-header .nav-link:focus {
    background: var(--townsy-bg-light);
    color: var(--townsy-primary-light) !important;
}
/* Current page — a filled pill.

   Two earlier versions were worse. Gold text alone sat at 2.22:1 and signalled
   the current page by colour only (WCAG 1.4.3 and 1.4.1). Replacing it with an
   inset underline fixed the contrast, but an inset shadow follows the element's
   border-radius, so the ends of the line curled up around the corners.

   Reusing the hover fill was the obvious next idea and does not work either:
   --townsy-bg-light is 1.09:1 against the white header, which reads as a
   transient hover cue but disappears as a permanent marker — and it would make
   hovering any other item look identical to the page you are on.

   Inverting the pill is unambiguous at a glance, needs no line to curve, and
   stays distinct from hover. White on --townsy-primary is 8.94:1 here, and the
   variable API already requires primary to carry white text.
   The matching aria-current="page" is emitted by townsy_nav_menu(). */
.site-header .nav-link.active,
.site-header .nav-link.active:hover,
.site-header .nav-link.active:focus,
.site-header .nav-link.active:focus-visible {
    background: var(--townsy-primary);
    color: var(--townsy-white) !important;
}

/* A parent whose dropdown contains the current page — "you are in this
   section", as against "this is the page you are on". WordPress marks that item
   current-menu-ancestor and the walker passes it to the <li>; only the page
   itself carries aria-current, which is correct, since the parent is not the
   current page, it merely contains it.

   Filled in --townsy-primary-light rather than tinted toward white. A pale
   tint of the primary measures around 1.1:1 against the white header — the
   same invisibility that ruled out reusing the hover fill — whereas a lighter
   solid reads clearly while still sitting below the current page in weight.

   White text on it needs no separate check: VARIABLES.md already requires
   --townsy-primary-light to clear 4.5:1 against white, and contrast is
   symmetric, so any palette that satisfies the documented contract satisfies
   this too.

   :not(.active) matters. A top-level item that is itself the current page and
   also has children matches both rules, and this one is the more specific, so
   without the exclusion the actual current page would render in the weaker
   ancestor colour. */
.site-header .nav-item.active > .nav-link:not(.active),
.site-header .nav-item.active > .nav-link:not(.active):hover,
.site-header .nav-item.active > .nav-link:not(.active):focus,
.site-header .nav-item.active > .nav-link:not(.active):focus-visible {
    background: var(--townsy-primary-light);
    color: var(--townsy-white) !important;
}

/* Dropdowns */
.site-header .dropdown-menu {
    border: none;
    box-shadow: var(--townsy-shadow-md);
    border-radius: var(--townsy-radius);
    border-top: 3px solid var(--townsy-secondary);
    min-width: 220px;
}
.site-header .dropdown-item {
    font-size: .9rem;
    color: var(--townsy-text);
    padding: .55rem 1.1rem;
}
.site-header .dropdown-item:hover {
    background: var(--townsy-bg-light);
    color: var(--townsy-primary);
}

/* The current page inside a dropdown. Without this it falls through to
   Bootstrap's default .dropdown-item.active, which is Bootstrap blue (#0d6efd)
   with the theme's near-black text over it — off-brand in any town's palette,
   and 3.91:1, under the 4.5:1 this size of text needs. Matching the top-level
   pill fixes both and makes the two levels read as the same idea. */
.site-header .dropdown-item.active,
.site-header .dropdown-item.active:hover,
.site-header .dropdown-item.active:focus {
    background: var(--townsy-primary);
    color: var(--townsy-white);
}

/* =========================================================
   HERO / TOP SECTION
   ========================================================= */

.hero-section {
    position: relative;
    overflow: hidden;
    background: var(--townsy-primary);
    min-height: 420px;
}

.hero-section .hero-image {
    width: 100%;
    height: 480px;
    object-fit: cover;
    display: block;
}

.hero-section .hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(0,0,0,.15) 0%, rgba(0,0,0,.55) 100%);
}

.hero-section .hero-content {
    position: absolute;
    bottom: 2.5rem;
    left: 0; right: 0;
    color: var(--townsy-white);
    text-shadow: 0 2px 8px rgba(0,0,0,.4);
}

.hero-section .hero-heading {
    font-size: clamp(1.8rem, 4vw, 3rem);
    font-weight: 800;
    line-height: 1.15;
    margin-bottom: .4rem;
}

.hero-section .hero-subheading {
    font-size: clamp(1rem, 2vw, 1.35rem);
    font-weight: 400;
    opacity: .92;
}

/* Carousel controls override */
.hero-section .carousel-control-prev,
.hero-section .carousel-control-next {
    width: 48px;
    opacity: .8;
}

/* =========================================================
   SHORTCUT LINKS ROW
   ========================================================= */

.shortcut-links-row {
    background: var(--townsy-white);
    border-bottom: 1px solid var(--townsy-border);
    padding: 1.25rem 0;
    box-shadow: var(--townsy-shadow);
}

.shortcut-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    padding: .85rem 1rem;
    border: 1.5px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    color: var(--townsy-primary);
    font-size: .85rem;
    font-weight: 600;
    text-align: center;
    transition: all .18s;
    background: var(--townsy-white);
    text-decoration: none;
}
.shortcut-card:hover {
    background: var(--townsy-primary);
    border-color: var(--townsy-primary);
    color: var(--townsy-white);
    text-decoration: none;
    transform: translateY(-2px);
    box-shadow: var(--townsy-shadow-md);
}
.shortcut-card .shortcut-icon {
    font-size: 1.6rem;
    line-height: 1;
}

/* =========================================================
   PAGE HEADER (inner pages)
   ========================================================= */

.page-header-section {
    background: var(--townsy-primary);
    color: var(--townsy-white);
    padding: 2.5rem 0 2rem;
    position: relative;
    overflow: hidden;
}

.page-header-section .page-header-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    opacity: .25;
}

.page-header-section .page-title {
    font-size: clamp(1.5rem, 3vw, 2.2rem);
    font-weight: 800;
    position: relative;
}

/* =========================================================
   SIDEBAR (indexed pages)
   ========================================================= */

/* Sticky wherever the sidebar is shown (md and up; below that the
   jump-to-section select replaces it). It used to go static under 992px,
   which is exactly an iPad in portrait, where it still sits beside the
   content. A long list scrolls inside itself rather than off the screen. */
.toc-sidebar {
    position: sticky;
    top: calc(var(--townsy-header-height) + 1.5rem);
    max-height: calc(100vh - var(--townsy-header-height) - 3rem);
    overflow-y: auto;
    /* A scrolling box clips anything outside it, and the focus ring sits
       5px outside each link (3px outline + 2px offset). The padding gives
       it room; the negative margin keeps the sidebar where it was. */
    padding: 6px;
    margin: -6px;
}

.toc-sidebar .toc-heading {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--townsy-text-muted);
    margin-bottom: .75rem;
}

.toc-sidebar .nav-link {
    font-size: .88rem;
    color: var(--townsy-text);
    padding: .35rem .75rem;
    border-left: 2px solid var(--townsy-border);
    border-radius: 0 var(--townsy-radius) var(--townsy-radius) 0;
    transition: all .15s;
}
.toc-sidebar .nav-link:hover,
.toc-sidebar .nav-link.active {
    color: var(--townsy-primary);
    border-left-color: var(--townsy-primary);
    background: var(--townsy-bg-light);
}

/* =========================================================
   CONTENT SECTIONS
   ========================================================= */

.content-section {
    padding: 3rem 0;
    border-bottom: 1px solid var(--townsy-border);
}
.content-section:last-child { border-bottom: none; }

.content-section .section-heading {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--townsy-primary);
    margin-bottom: 1.25rem;
    padding-top: .5rem;
}

/* =========================================================
   DEPARTMENT / GOVERNMENT PAGE CARDS
   ========================================================= */

.dept-card {
    border: 1.5px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    transition: box-shadow .18s, transform .18s;
    overflow: hidden;
    background: var(--townsy-white);
    text-decoration: none;
    color: inherit;
    display: block;
}
.dept-card:hover {
    box-shadow: var(--townsy-shadow-md);
    transform: translateY(-2px);
    text-decoration: none;
    color: inherit;
}
.dept-card .dept-card-body {
    padding: 1.25rem;
}
.dept-card .dept-card-title {
    font-weight: 700;
    color: var(--townsy-primary);
    font-size: 1rem;
    margin-bottom: .3rem;
}

/* =========================================================
   STAFF DIRECTORY
   ========================================================= */

.staff-card {
    background: var(--townsy-white);
    border: 1.5px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    overflow: hidden;
    text-align: center;
}
.staff-card img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    object-position: top;
}
.staff-card .staff-card-body {
    padding: 1rem;
}
.staff-card .staff-name {
    font-weight: 700;
    font-size: 1rem;
    color: var(--townsy-primary);
}
.staff-card .staff-title {
    font-size: .85rem;
    color: var(--townsy-text-muted);
}

/* =========================================================
   STAFF DIRECTORY — Horizontal list layout
   ========================================================= */
.staff-list-item {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--townsy-border);
}
.staff-list-item:last-child {
    border-bottom: none;
}
.staff-list-photo {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    object-fit: cover;
    object-position: top;
    flex-shrink: 0;
    border: 2px solid var(--townsy-border);
}
.staff-list-placeholder {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--townsy-bg-light);
    border: 2px solid var(--townsy-border);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.staff-list-body {
    flex: 1;
    min-width: 0;
}
.staff-list-name {
    font-weight: 700;
    font-size: 1rem;
    color: var(--townsy-primary);
    margin-bottom: .1rem;
}
.staff-list-title {
    font-size: .85rem;
    color: var(--townsy-text-muted);
    margin-bottom: .25rem;
}
.staff-list-dept {
    display: inline-block;
    font-size: .8rem;
    font-weight: 600;
    color: var(--townsy-secondary);
    text-decoration: none;
    margin-bottom: .35rem;
}
.staff-list-dept:hover {
    text-decoration: underline;
    color: var(--townsy-secondary);
}
.staff-list-dept i {
    opacity: .7;
}
.staff-list-contact a {
    display: inline-block;
    font-size: .82rem;
    color: var(--townsy-text);
    text-decoration: none;
    margin-right: 1rem;
}
.staff-list-contact a:hover {
    color: var(--townsy-primary);
    text-decoration: underline;
}

/* =========================================================
   JOB LISTINGS
   ========================================================= */

.job-listing-item {
    background: var(--townsy-white);
    border: 1.5px solid var(--townsy-border);
    border-left: 4px solid var(--townsy-secondary);
    border-radius: var(--townsy-radius);
    padding: 1.25rem 1.5rem;
    margin-bottom: 1rem;
}
.job-listing-item .job-title {
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--townsy-primary);
}
.job-listing-item .job-meta {
    font-size: .85rem;
    color: var(--townsy-text-muted);
}

/* =========================================================
   THINGS TO DO
   ========================================================= */

.things-card {
    border: 1.5px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    overflow: hidden;
    background: var(--townsy-white);
    height: 100%;
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    transition: box-shadow .18s, transform .18s;
}
.things-card:hover {
    box-shadow: var(--townsy-shadow-md);
    transform: translateY(-2px);
    text-decoration: none;
    color: inherit;
}
.things-card img {
    height: 200px;
    width: 100%;
    object-fit: cover;
}
.things-card .things-card-body {
    padding: 1rem 1.1rem;
    flex: 1;
}
.things-card .things-card-title {
    font-weight: 700;
    color: var(--townsy-primary);
    font-size: 1rem;
}

/* Info box (phone/address/hours) */
.info-box {
    background: var(--townsy-bg-light);
    border: 1.5px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    padding: 1.25rem 1.5rem;
}
.info-box .info-item {
    display: flex;
    gap: .65rem;
    align-items: flex-start;
    margin-bottom: .65rem;
    font-size: .92rem;
}
.info-box .info-item:last-child { margin-bottom: 0; }
.info-box .info-icon {
    color: var(--townsy-primary);
    min-width: 1.1rem;
    margin-top: .15rem;
}

/* =========================================================
   CARE SERVICES
   ========================================================= */

.care-service-card {
    position: relative; /* contain Bootstrap stretched-link ::after pseudo-element */
    background: var(--townsy-white);
    border: 1.5px solid var(--townsy-border);
    border-top: 4px solid var(--townsy-secondary);
    border-radius: var(--townsy-radius);
    padding: 1.5rem;
}

.care-service-card img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: calc(var(--townsy-radius) - 2px);
}

/* =========================================================
   POPULAR LINKS SIDEBAR
   ========================================================= */

.popular-links-widget {
    background: var(--townsy-bg-light);
    border-radius: var(--townsy-radius);
    padding: 1.25rem;
}
/* Matches h2 and h3 so the widget keeps its eyebrow styling regardless of the
   heading level the surrounding page needs for a correct outline. */
.popular-links-widget h2,
.popular-links-widget h3 {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    font-weight: 700;
    color: var(--townsy-text-muted);
    margin-bottom: .85rem;
}
.popular-links-widget a {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem 0;
    font-size: .9rem;
    color: var(--townsy-primary);
    border-bottom: 1px solid var(--townsy-border);
}
.popular-links-widget a:last-child { border-bottom: none; }
.popular-links-widget a:hover { color: var(--townsy-primary-light); text-decoration: none; }

/* =========================================================
   NEWS PANEL  (Life in Town page)

   A contained card rather than a full-bleed band. It sits in normal flow by
   default; a town that wants the card lifted over the hero above it can pull
   it up without touching a template:
       :root { --townsy-news-panel-overlap: 7rem; }

   The value is how far the card is pulled up from where it would otherwise
   sit. <main> carries one --townsy-section-space of top padding, so anything
   under that only eats into the gap and larger values overlap the hero itself.
   A town adding a lift should check small screens, where the hero is shorter.
   ========================================================= */

.news-panel-section {
    position: relative;
    z-index: 2;                 /* so a lifted card sits above the hero */
    margin-top: calc(-1 * var(--townsy-news-panel-overlap, 0px));
    /* This section has no padding of its own, so it supplies one unit of the
       page rhythm itself. Without it the card crowds the divider beneath it
       while every other section sits a full unit clear of its boundary. */
    padding-bottom: var(--townsy-section-space, 3rem);
}

.news-panel {
    position: relative;
    max-width: 960px;
    margin-inline: auto;
    border-radius: var(--townsy-radius);
    overflow: hidden;           /* keeps the background inside the rounded corners */
    box-shadow: var(--townsy-shadow-md);
    background-color: var(--townsy-primary);   /* also the fallback when no image is set */
    background-size: cover;
    background-position: center;
    color: var(--townsy-white);
}

/* Darkens whatever photo a town uploads so the white text stays legible.
   At 0.6 even a near-white image leaves white text above 4.5:1 — the scrim,
   not the photo, is what carries the contrast, which matters because the
   image is chosen by the town and cannot be checked in advance. */
.news-panel-scrim {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .6);
}

.news-panel-body {
    position: relative;         /* above the scrim */
    padding: 3.25rem 1.5rem;
}

.news-panel-heading {
    font-size: var(--townsy-h2-size);
    font-weight: 700;
    color: var(--townsy-white);
    margin-bottom: .75rem;
}

.news-panel-sub {
    font-size: var(--townsy-text-lg);
    max-width: 46rem;           /* keeps the line length readable */
    margin: 0 auto 1.5rem;
    color: rgba(255, 255, 255, .92);
}

@media (max-width: 767.98px) {
    .news-panel-body { padding: 2.25rem 1.25rem; }
}

/* =========================================================
   FLEXIBLE CONTENT LAYOUTS
   ========================================================= */

.flex-section {
    padding: 2.5rem 0;
    border-bottom: 1px solid var(--townsy-border);
}
.flex-section:last-child { border-bottom: none; }

/* =========================================================
   FOOTER
   ========================================================= */

.site-footer {
    background: var(--townsy-primary);
    color: var(--townsy-footer-text);
    padding: 3rem 0 1.5rem;
    font-size: .9rem;
}

.site-footer .footer-logo img {
    max-height: 60px;
    width: auto;
    opacity: .9;
    margin-bottom: 1rem;
}

.site-footer .footer-col-heading {
    color: var(--townsy-white);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    margin-bottom: .85rem;
    padding-bottom: .4rem;
    border-bottom: 2px solid var(--townsy-secondary);
    display: inline-block;
}

.site-footer a {
    color: rgba(255,255,255,.75);
    text-decoration: none;
    transition: color .15s;
}
.site-footer a:hover {
    color: var(--townsy-white);
    text-decoration: none;
}

/* Nav column links — list reset + block stacking */
.site-footer .footer-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.site-footer .footer-nav-list li {
    padding: 0;
}
.site-footer nav a {
    display: block;
    padding: .2rem 0;
}

/* Contact detail links (phone, email) stay inline with their icon */
.site-footer .footer-contact-detail a {
    display: inline;
}

.site-footer .social-links {
    display: flex;
    gap: .75rem;
    flex-wrap: wrap;
    margin-top: .5rem;
}
.site-footer .social-links a {
    width: 36px; height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,.12);
    border-radius: 50%;
    font-size: 1rem;
    color: var(--townsy-white);
    transition: background .15s;
    padding: 0;
}
.site-footer .social-links a:hover {
    background: var(--townsy-secondary);
}

.site-footer .footer-bottom {
    border-top: 1px solid rgba(255,255,255,.15);
    margin-top: 2rem;
    padding-top: 1rem;
    font-size: .8rem;
    color: var(--townsy-footer-text-dim);
}

.site-footer .footer-powered a {
    display: inline;
    color: rgba(255,255,255,.6);
    padding: 0;
}
.site-footer .footer-powered a:hover {
    color: var(--townsy-white);
}

/* =========================================================
   UTILITIES
   ========================================================= */

.btn-primary-townsy {
    background: var(--townsy-primary);
    border-color: var(--townsy-primary);
    color: var(--townsy-white);
    font-weight: 600;
    border-radius: var(--townsy-radius);
    padding: .55rem 1.4rem;
    transition: background .15s, box-shadow .15s;
}
.btn-primary-townsy:hover {
    background: var(--townsy-primary-light);
    border-color: var(--townsy-primary-light);
    color: var(--townsy-white);
    box-shadow: var(--townsy-shadow);
}

.btn-secondary-townsy {
    background: var(--townsy-secondary);
    border-color: var(--townsy-secondary);
    color: var(--townsy-primary);
    font-weight: 600;
    border-radius: var(--townsy-radius);
    padding: .55rem 1.4rem;
    transition: background .15s;
}
.btn-secondary-townsy:hover {
    background: var(--townsy-secondary-dark);
    border-color: var(--townsy-secondary-dark);
    color: var(--townsy-white);
}

.section-label {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--townsy-label-color);   /* #7a5500 dark amber — 6.5:1 on white (was gold #e8a020 ~1.5:1, fail) */
    display: block;
    margin-bottom: .35rem;
}

.townsy-divider {
    height: 3px;
    width: 48px;
    background: var(--townsy-secondary);
    border: none;
    margin: .75rem 0 1.5rem;
    border-radius: 2px;
}

/* =========================================================
   RESPONSIVE
   ========================================================= */

@media (max-width: 991.98px) {
    .hero-section .hero-image { height: 320px; }
    .shortcut-card { font-size: .78rem; padding: .65rem .5rem; }
/* Mobile TOC jump select — indexed pages, small screens only */
.toc-mobile-select {
    border-color: var(--townsy-border);
    border-radius: var(--townsy-radius);
    font-size: .9rem;
    margin-bottom: 0;
}

}

@media (max-width: 575.98px) {
    .hero-section .hero-image { height: 240px; }
    .hero-section .hero-heading { font-size: 1.5rem; }
}

/* =========================================================
   SEARCH TOGGLE & BAR
   ========================================================= */

/* Toggle button sits at the right end of the navbar */
.site-search-toggle {
    background: none;
    border: 1.5px solid var(--townsy-border);
    color: var(--townsy-primary);
    border-radius: var(--townsy-radius);
    padding: .4rem .65rem;
    font-size: 1rem;
    line-height: 1;
    display: flex;
    align-items: center;
    gap: .35rem;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.site-search-toggle:hover,
.site-search-toggle[aria-expanded="true"] {
    background: var(--townsy-bg-light);
    border-color: var(--townsy-primary);
}

/* Expandable search bar below the sticky header */
.site-search-bar {
    background: var(--townsy-bg-light);
    border-bottom: 2px solid var(--townsy-secondary);
    box-shadow: var(--townsy-shadow-md);
}
/* The [hidden] attribute hides it; JS toggles that attribute */
.site-search-bar[hidden] { display: none; }

/* =========================================================
   ACCESSIBILITY
   WCAG 2.1 AA / Section 508 compliance layer.
   Keep this section at the bottom so it wins specificity.
   ========================================================= */

/* ---------------------------------------------------------
   Skip-to-content link (WCAG 2.4.1 — Bypass Blocks)
   First focusable element; visible only on keyboard focus.
   --------------------------------------------------------- */
.skip-to-content {
    position: absolute;
    top: -100%;
    left: 1rem;
    z-index: 9999;
    background: var(--townsy-primary);
    color: var(--townsy-white);
    padding: .65rem 1.5rem;
    border-radius: 0 0 var(--townsy-radius) var(--townsy-radius);
    font-weight: 700;
    font-size: .95rem;
    text-decoration: none;
    white-space: nowrap;
    transition: top .15s ease;
}
/* The skip link sits on --townsy-primary, so it is the clearest case for the
   two-tone ring: the light inner ring is what carries contrast against the dark
   panel, while the outline carries it against the page beyond. */
.skip-to-content:focus {
    top: 0;
    color: var(--townsy-white);
    outline: 3px solid var(--townsy-focus-ring);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--townsy-focus-ring-inverse);
    text-decoration: none;
}

/* ---------------------------------------------------------
   Global focus styles (WCAG 2.4.7 — Focus Visible)
   Provide a clear, high-contrast focus indicator for all
   interactive elements when navigated by keyboard.
   --------------------------------------------------------- */

/* Keyboard focus only — do not show ring for mouse clicks */
:focus:not(:focus-visible) {
    outline: none;
    box-shadow: none;
}

/* Two-tone ring. The inner light ring (box-shadow) sits in the gap opened by
   outline-offset, with the darker outline around it. On a light background the
   outline carries the contrast; on a dark one (footer, skip link, banners) the
   inner ring does. The two also contrast against each other, so the indicator
   never disappears and no section needs its own focus override.

   Previously both rings were --townsy-secondary, which VARIABLES.md declares
   decorative precisely because it fails contrast: the default gold measured
   2.22:1 against white where SC 1.4.11 requires 3:1. */
:focus-visible {
    outline: 3px solid var(--townsy-focus-ring);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--townsy-focus-ring-inverse);
    border-radius: 2px;
}

/* Reinforce focus for interactive components, adding the ambient brand glow
   outside the ring. The two-tone ring is repeated here so the glow does not
   replace the inner light ring. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.nav-link:focus-visible,
.shortcut-card:focus-visible,
.dept-card:focus-visible,
.things-card:focus-visible {
    outline: 3px solid var(--townsy-focus-ring);
    outline-offset: 2px;
    box-shadow:
        0 0 0 2px var(--townsy-focus-ring-inverse),
        0 0 0 9px var(--townsy-secondary-focus-glow);
}

/* Ensure nav-link active/hover doesn't clobber outline */
.site-header .nav-link:focus-visible {
    outline: 3px solid var(--townsy-focus-ring);
    outline-offset: 2px;
    background: var(--townsy-bg-light);
}

/* ---------------------------------------------------------
   Announcement bar pause button
   (WCAG 2.2.2 — Pause, Stop, Hide)
   --------------------------------------------------------- */
.announcement-pause-btn {
    flex-shrink: 0;
    background: none;
    border: 1.5px solid rgba(255, 255, 255, .55);
    color: var(--townsy-white);
    border-radius: 50%;
    width: 28px;
    height: 28px;
    min-width: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    font-size: .8rem;
    transition: background .15s, border-color .15s;
    line-height: 1;
}
.announcement-pause-btn:hover {
    background: rgba(255, 255, 255, .15);
    border-color: rgba(255, 255, 255, .9);
}
.announcement-pause-btn:focus-visible {
    outline: 2px solid var(--townsy-focus-ring-inverse);
    outline-offset: 2px;
    background: rgba(255, 255, 255, .15);
}

/* ---------------------------------------------------------
   Hero carousel pause button
   (WCAG 2.2.2 — Pause, Stop, Hide)
   --------------------------------------------------------- */
.carousel-pause-btn {
    position: absolute;
    bottom: 1rem;
    right: 1rem;
    z-index: 20;
    background: rgba(0, 0, 0, .5);
    border: 2px solid rgba(255, 255, 255, .75);
    border-radius: 50%;
    width: 40px;
    height: 40px;
    color: var(--townsy-white);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    font-size: 1rem;
    transition: background .15s;
}
.carousel-pause-btn:hover {
    background: rgba(0, 0, 0, .75);
}
.carousel-pause-btn:focus-visible {
    outline: 2px solid var(--townsy-white);
    outline-offset: 2px;
    background: rgba(0, 0, 0, .75);
}

/* ---------------------------------------------------------
   Breadcrumb link contrast fix
   (WCAG 1.4.3 — Contrast Minimum)
   Inline styles on breadcrumbs used rgba(255,255,255,.7) which
   can fall short of 4.5:1. These selectors override via class.
   --------------------------------------------------------- */
.breadcrumb-accessible-link {
    color: rgba(255, 255, 255, .88) !important;
    text-decoration-color: rgba(255, 255, 255, .5);
}
/* Active (non-linked) breadcrumb item on dark backgrounds */
.breadcrumb-item.active {
    color: rgba(255, 255, 255, .88);
}
/* Divider "/" between breadcrumb items on dark backgrounds */
.breadcrumb-item + .breadcrumb-item::before {
    color: rgba(255, 255, 255, .55);
}
.breadcrumb-accessible-link:hover {
    color: var(--townsy-white) !important;
    text-decoration: underline;
}

/* On-light variant — breadcrumbs that sit on a white/light background.
   Apply class="breadcrumb--on-light" to the <nav>.
   Swap --townsy-breadcrumb-link-color per client in :root to restyle. */
.breadcrumb--on-light .breadcrumb-accessible-link {
    color: var(--townsy-breadcrumb-link-color) !important;
    text-decoration-color: rgba(0, 0, 0, .2);
}
.breadcrumb--on-light .breadcrumb-accessible-link:hover {
    color: var(--townsy-breadcrumb-link-color-hover) !important;
    text-decoration: underline;
}
.breadcrumb--on-light .breadcrumb-item.active {
    color: var(--townsy-text-muted);
}

/* ---------------------------------------------------------
   prefers-reduced-motion
   (WCAG 2.3.3 — Animation from Interactions)
   Disable all non-essential motion for users who prefer it.
   --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    /* Kill all transitions and animations globally */
    *,
    *::before,
    *::after {
        animation-duration:        0.01ms !important;
        animation-iteration-count: 1      !important;
        transition-duration:       0.01ms !important;
        scroll-behavior:           auto   !important;
    }

    /* Announcement cycler: disable jiggle, just show current item */
    .announce-item.is-active {
        animation: none;
    }

    /* Hero image still visible, just no parallax/fade */
    .hero-section .hero-image {
        transition: none;
    }

    /* Card hover transforms */
    .shortcut-card:hover,
    .dept-card:hover,
    .things-card:hover {
        transform: none;
    }
}

/* ---------------------------------------------------------
   Staff Directory — responsive table
   Used on the /government/staff-directory/ page.
   Collapses to labeled stacked rows on mobile.
   --------------------------------------------------------- */
.staff-dir-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.staff-dir-table {
    border-collapse: collapse;
    min-width: 560px;
}
.staff-dir-th {
    padding: .6rem 1rem;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--townsy-text-muted);
    border-bottom: 2px solid var(--townsy-border);
    text-align: left;
    white-space: nowrap;
}
.staff-dir-row {
    border-bottom: 1px solid var(--townsy-border);
    transition: background .15s;
}
.staff-dir-row:last-child { border-bottom: none; }
.staff-dir-row:hover { background: var(--townsy-bg-light); }
.staff-dir-td {
    padding: .9rem 1rem;
    vertical-align: middle;
    font-size: .92rem;
    color: var(--townsy-text);
}
.staff-dir-photo-cell {
    width: 72px;
    min-width: 72px;   /* prevents column from squishing on mid-size desktops */
    padding-right: .5rem;
}
.staff-dir-photo,
.staff-dir-photo-placeholder {
    width: 56px;
    height: 56px;
    min-width: 56px;   /* hard floor — never smaller than this */
    border-radius: 6px;
    object-fit: cover;
    object-position: top;
    border: 1px solid var(--townsy-border);
    display: block;
}
.staff-dir-photo-placeholder {
    background: var(--townsy-bg-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: var(--townsy-border);
}
.staff-dir-name {
    font-weight: 600;
    color: var(--townsy-text);
}
.staff-dir-dept-link,
.staff-dir-contact-link {
    color: var(--townsy-primary-light);
    text-decoration: none;
    font-size: .88rem;
}
.staff-dir-dept-link:hover,
.staff-dir-contact-link:hover {
    text-decoration: underline;
    color: var(--townsy-primary);
}

/* Responsive stacked layout on small screens */
@media (max-width: 575px) {
    .staff-dir-table,
    .staff-dir-table thead,
    .staff-dir-table tbody,
    .staff-dir-table tr,
    .staff-dir-table td { display: block; width: 100%; }
    .staff-dir-table thead { display: none; }
    .staff-dir-row {
        padding: .75rem 0;
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        gap: .25rem .75rem;
    }
    .staff-dir-td { padding: .15rem .5rem; border: none; }
    .staff-dir-photo-cell { width: 100%; }
    .staff-dir-td[data-label]::before {
        content: attr(data-label) ': ';
        font-weight: 700;
        font-size: .75rem;
        text-transform: uppercase;
        color: var(--townsy-text-muted);
    }
}

/* ---------------------------------------------------------
   Care Services directory (archive-resident-information.php)
   Compact two-column rows grouped under care-type headings.
   --------------------------------------------------------- */
.cs-directory-heading {
    gap: 1rem;
}
.cs-directory-see-all {
    color: var(--townsy-secondary);
    white-space: nowrap;
}
.cs-directory-see-all:hover {
    color: var(--townsy-primary);
}
.cs-directory-item {
    border-radius: var(--townsy-radius);
    border: 1px solid var(--townsy-border);
    background: var(--townsy-white);
    transition: border-color .18s, box-shadow .18s, transform .18s;
}
.cs-directory-item:hover {
    border-color: var(--townsy-primary);
    box-shadow: 0 2px 10px rgba(0,0,0,.07);
    transform: translateY(-2px);
}
.cs-directory-item-icon {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--townsy-bg-light);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--townsy-primary);
    font-size: 1rem;
}
.cs-directory-item-name {
    font-weight: 600;
    font-size: .95rem;
    color: var(--townsy-primary);
    line-height: 1.3;
}
.cs-directory-item-meta {
    font-size: .78rem;
    color: var(--townsy-text-muted);
    line-height: 1.5;
}

/* ---------------------------------------------------------
   Council Members cards (single-government-page.php)
   Displayed only on the Mayor & Council government-page.
   --------------------------------------------------------- */
.council-member-card {
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    background: var(--townsy-white);
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: row;
    align-items: stretch;
}
.council-member-photo {
    width: 120px;
    min-width: 120px;
    height: 100%;
    min-height: 120px;
    object-fit: cover;
    object-position: top center;
    display: block;
    flex-shrink: 0;
}
.council-member-photo-placeholder {
    width: 120px;
    min-width: 120px;
    background: var(--townsy-bg-light);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--townsy-border);
    font-size: 2.5rem;
    flex-shrink: 0;
}
.council-member-body {
    padding: .85rem 1rem;
    display: flex;
    flex-direction: column;
    gap: .2rem;
    flex: 1;
    justify-content: center;
}
.council-member-name {
    font-weight: 700;
    font-size: 1rem;
    color: var(--townsy-primary);
    margin: 0;
    line-height: 1.3;
}
.council-member-title {
    font-size: .85rem;
    color: var(--townsy-text-muted);
    margin: 0;
    line-height: 1.4;
}
.council-member-email {
    font-size: .82rem;
    color: var(--townsy-primary-light);
    text-decoration: none;
    margin-top: .35rem;
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    word-break: break-all;
}
.council-member-email:hover {
    color: var(--townsy-primary);
    text-decoration: underline;
}

/* ---------------------------------------------------------
   Document Library — page-meetings-agendas.php
   Bootstrap accordion + document table for city-document CPT.
   --------------------------------------------------------- */

/* Accordion shell */
.doc-accordion {
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    overflow: hidden;
}
.doc-accordion-item {
    border: none;
    border-bottom: 1px solid var(--townsy-border);
}
.doc-accordion-item:last-child {
    border-bottom: none;
}

/* Accordion button */
.doc-accordion-btn {
    background: var(--townsy-bg-light);
    color: var(--townsy-primary);
    font-weight: 700;
    font-size: 1rem;
    padding: .85rem 1.25rem;
    border-radius: 0 !important;
    box-shadow: none !important;
    display: flex;
    align-items: center;
    gap: .6rem;
}
.doc-accordion-btn:not(.collapsed) {
    background: var(--townsy-primary);
    color: var(--townsy-white);
}
.doc-accordion-btn::after {
    /* Bootstrap's default chevron; tint it to match */
    filter: none;
    margin-left: auto;
    flex-shrink: 0;
}
.doc-accordion-btn:not(.collapsed)::after {
    filter: brightness(10);
}

/* Document count badge in accordion header */
.doc-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 .45rem;
    border-radius: 999px;
    background: rgba(255,255,255,.25);
    color: inherit;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1;
}
.doc-accordion-btn:not(.collapsed) .doc-count {
    background: rgba(255,255,255,.25);
    color: var(--townsy-white);
}
.doc-accordion-btn.collapsed .doc-count {
    background: var(--townsy-primary);
    color: var(--townsy-white);
}

/* Accordion body */
.doc-accordion-body {
    padding: 0;
}
.doc-group-desc {
    padding: .75rem 1.25rem .25rem;
    font-size: .88rem;
    color: var(--townsy-text-muted);
    margin: 0;
}

/* Document table */
.doc-table {
    border-collapse: collapse;
}
.doc-th {
    padding: .6rem 1.25rem;
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--townsy-text-muted);
    border-bottom: 1px solid var(--townsy-border);
    background: var(--townsy-white);
    white-space: nowrap;
}
.doc-th-date  { width: 140px; }
.doc-th-action { width: 130px; }
.doc-row {
    border-bottom: 1px solid var(--townsy-border);
    transition: background .15s;
}
.doc-row:last-child { border-bottom: none; }
.doc-row:hover { background: var(--townsy-bg-light); }

/* The year filter hides rows by setting the [hidden] property. Bootstrap's
   Reboot already ships `[hidden] { display: none !important }`, which wins over
   the `display` declarations in the max-width:575px block below, so filtering
   works on phones with or without this rule — verified in-browser.

   It is kept only as insurance for the case where Bootstrap's CSS does not
   load, since the bare user-agent `[hidden]` rule would then lose to the
   stacked-table `display` declarations. Specificity here (0,2,0) clears both
   `.doc-row` (0,1,0) and `.doc-table tr` (0,1,1). */
.doc-row[hidden],
.doc-table[hidden] { display: none; }
.doc-td {
    padding: .75rem 1.25rem;
    vertical-align: middle;
    font-size: .92rem;
    color: var(--townsy-text);
}
.doc-td-date {
    color: var(--townsy-text-muted);
    white-space: nowrap;
}
.doc-td-action { text-align: right; }

/* Document name + optional description */
.doc-name {
    font-weight: 600;
    display: block;
    line-height: 1.35;
}
.doc-desc {
    display: block;
    font-size: .8rem;
    color: var(--townsy-text-muted);
    margin-top: .15rem;
}

/* File-type badge (PDF, DOCX, etc.) */
.doc-badge {
    display: inline-block;
    margin-top: .25rem;
    padding: .1rem .4rem;
    border-radius: 4px;
    background: var(--townsy-bg-light);
    border: 1px solid var(--townsy-border);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--townsy-text-muted);
    vertical-align: middle;
}

/* Admin list column badge */
.doc-badge-admin {
    display: inline-block;
    padding: .1rem .4rem;
    border-radius: 4px;
    background: #e8f0fe;
    border: 1px solid #c5d3f0;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: #1a56db;
}

/* Download button */
.doc-download-btn {
    white-space: nowrap;
}

/* Responsive: stack table on small screens */
@media (max-width: 575px) {
    .doc-table,
    .doc-table thead,
    .doc-table tbody,
    .doc-table tr,
    .doc-table td { display: block; width: 100%; }
    .doc-table thead { display: none; }
    .doc-row {
        padding: .75rem 1.25rem;
        display: flex;
        flex-wrap: wrap;
        gap: .35rem .75rem;
        align-items: center;
    }
    .doc-td { padding: 0; border: none; }
    .doc-td-action { margin-top: .35rem; text-align: left; }
}

/* ---------------------------------------------------------
   Document year filter bar
   --------------------------------------------------------- */

.doc-year-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}
.doc-year-filter-label {
    font-size: var(--townsy-text-sm);
    font-weight: 600;
    color: var(--townsy-primary);
    margin-right: .1rem;
    white-space: nowrap;
}
.doc-year-filter-btn {
    display: inline-flex;
    align-items: center;
    padding: .28rem .9rem;
    border-radius: 2rem;
    border: 1.5px solid var(--townsy-primary);
    background: transparent;
    color: var(--townsy-primary);
    font-size: var(--townsy-text-sm);
    font-weight: 500;
    line-height: 1.4;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.doc-year-filter-btn:hover {
    background: var(--townsy-primary);
    color: #fff;
}
.doc-year-filter-btn.active {
    background: var(--townsy-primary);
    color: #fff;
}
.doc-year-filter-btn:focus-visible {
    outline: 3px solid var(--townsy-focus-ring, #005fcc);
    outline-offset: 2px;
}

/* Empty-year message shown when a filtered panel has zero rows */
.doc-empty-year-msg {
    margin: .75rem 1.25rem;
    font-size: var(--townsy-text-sm);
    color: var(--townsy-muted, #6c757d);
    font-style: italic;
}

/* ---------------------------------------------------------
   File-type link badges — auto-prepended via CSS ::before
   Applies to any <a> inside .wp-content whose href ends with
   a recognised extension. No editor changes needed.
   --------------------------------------------------------- */

/* Shared badge styles */
.wp-content a[href$=".pdf"]::before,
.wp-content a[href$=".PDF"]::before,
.wp-content a[href$=".doc"]::before,
.wp-content a[href$=".DOC"]::before,
.wp-content a[href$=".docx"]::before,
.wp-content a[href$=".DOCX"]::before,
.wp-content a[href$=".xls"]::before,
.wp-content a[href$=".XLS"]::before,
.wp-content a[href$=".xlsx"]::before,
.wp-content a[href$=".XLSX"]::before,
.wp-content a[href$=".ppt"]::before,
.wp-content a[href$=".PPT"]::before,
.wp-content a[href$=".pptx"]::before,
.wp-content a[href$=".PPTX"]::before,
.wp-content a[href$=".csv"]::before,
.wp-content a[href$=".CSV"]::before {
    display: inline-block;
    font-size: .6rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .04em;
    padding: .2em .45em .2em .4em;
    border-radius: .25rem;
    margin-right: .35em;
    vertical-align: middle;
    position: relative;
    top: -.05em;
    color: #fff;
}

/* PDF — red */
.wp-content a[href$=".pdf"]::before,
.wp-content a[href$=".PDF"]::before {
    content: "PDF";
    background: #c0392b;
}

/* Word — blue */
.wp-content a[href$=".doc"]::before,
.wp-content a[href$=".DOC"]::before {
    content: "DOC";
    background: #2b5fbd;
}
.wp-content a[href$=".docx"]::before,
.wp-content a[href$=".DOCX"]::before {
    content: "DOC";
    background: #2b5fbd;
}

/* Excel — green */
.wp-content a[href$=".xls"]::before,
.wp-content a[href$=".XLS"]::before {
    content: "XLS";
    background: #1e7e45;
}
.wp-content a[href$=".xlsx"]::before,
.wp-content a[href$=".XLSX"]::before {
    content: "XLS";
    background: #1e7e45;
}

/* PowerPoint — orange */
.wp-content a[href$=".ppt"]::before,
.wp-content a[href$=".PPT"]::before {
    content: "PPT";
    background: #c55a11;
}
.wp-content a[href$=".pptx"]::before,
.wp-content a[href$=".PPTX"]::before {
    content: "PPT";
    background: #c55a11;
}

/* CSV — teal */
.wp-content a[href$=".csv"]::before,
.wp-content a[href$=".CSV"]::before {
    content: "CSV";
    background: #0e7b7b;
}

/* ---------------------------------------------------------
   Events page header — full-width breakout from TEC container
   tribe_events_before_html fires inside TEC's centered wrapper,
   so we use the negative-margin vw trick to restore edge-to-edge
   width, and a negative top margin to close the gap under the nav.
   --------------------------------------------------------- */
.page-header-section--events {
    /* Break out of TEC's centered container to full viewport width */
    width: 100vw;
    margin-left: calc(50% - 50vw);
    /* Pull up to sit flush under the nav gold border */
    margin-top: -50px;
}

/* Calendar views: TEC prints a screen-reader-only H1 ("Events") that
   duplicates the page header's. display:none takes it out of the
   accessibility tree, which visually-hidden styling does not. */
.tribe-events-header__content-title .tec-a11y-title-hidden {
    display: none;
}

/* =========================================================
   SINGLE EVENT
   Layout for TEC's own single-event markup plus the "at a glance"
   card from inc/events.php. Nothing here depends on a copied TEC
   template: if TEC renames a class, that piece falls back to TEC's
   default look rather than breaking the page.
   ========================================================= */

/* Replaced by the page header (breadcrumb + the event's name as the
   page's only H1) and by the at-a-glance card (date, time, cost, add to
   calendar, the Details box). The top prev/next nav duplicates the one
   at the foot of the page. */
.tribe-events-single .tribe-events-back,
.tribe-events-single .tribe-events-single-event-title,
.tribe-events-single .tribe-events-schedule,
.tribe-events-single #tribe-events-header,
.tribe-events-single .tribe-events-c-subscribe-dropdown__container,
.tribe-events-single .tribe-events-meta-group-details {
    display: none;
}

/* Matches the py-5 opening of other inner pages. */
.tribe-events-single {
    padding-top: 3rem;
}

/* Photo: a consistent 16:9 frame whatever the clerk uploads, so a tall
   phone photo does not push everything below the fold. */
.tribe-events-single .tribe-events-event-image {
    margin: 0 0 2rem;
}
.tribe-events-single .tribe-events-event-image img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--townsy-radius);
}

/* Description: a comfortable reading measure. */
.tribe-events-single .tribe-events-single-event-description {
    max-width: 68ch;
    font-size: 1.125rem;
    line-height: 1.7;
    margin-bottom: 2.5rem;
}

/* ---------- At a glance card ---------- */

.event-glance {
    margin: 0 0 2rem;
    background: var(--townsy-white);
    border: 1px solid var(--townsy-border);
    border-top: 4px solid var(--townsy-secondary);
    border-radius: var(--townsy-radius);
    box-shadow: var(--townsy-shadow);
    padding: 1.5rem;
}

.event-glance__top {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

/* A tear-off calendar page. */
.event-glance__date {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 4.75rem;
    overflow: hidden;
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    text-align: center;
    line-height: 1;
}
.event-glance__month {
    align-self: stretch;
    padding: .35rem 0;
    background: var(--townsy-primary);
    color: var(--townsy-white);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}
.event-glance__day {
    padding: .4rem 0 .1rem;
    font-size: 2rem;
    font-weight: 800;
    color: var(--townsy-text);
}
.event-glance__weekday {
    padding-bottom: .45rem;
    font-size: .75rem;
    font-weight: 600;
    color: var(--townsy-text-muted);
    text-transform: uppercase;
    letter-spacing: .06em;
}

.event-glance__status {
    margin: 0;
    padding: .3rem .7rem;
    border-radius: 999px;
    font-size: .85rem;
    font-weight: 700;
    background: var(--townsy-bg-light);
    color: var(--townsy-text);
}
.event-glance__status--now,
.event-glance__status--soon {
    background: var(--townsy-primary);
    color: var(--townsy-white);
}
.event-glance__status--past {
    color: var(--townsy-text-muted);
    font-weight: 600;
}

.event-glance__facts {
    margin: 0 0 1.25rem;
}
.event-glance__fact {
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr);
    gap: .5rem;
    padding: .75rem 0;
    border-top: 1px solid var(--townsy-border);
}
.event-glance__fact dt {
    color: var(--townsy-primary);
    font-size: 1.05rem;
    line-height: 1.5;
}
.event-glance__fact dd {
    margin: 0;
    line-height: 1.5;
}
.event-glance__fact dd strong {
    display: block;
}
.event-glance__address {
    display: block;
    color: var(--townsy-text-muted);
    font-size: .95rem;
}

.event-glance__tags {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}
.event-glance__tag {
    display: inline-block;
    padding: .15rem .6rem;
    border: 1px solid var(--townsy-border);
    border-radius: 999px;
    font-size: .85rem;
    color: var(--townsy-text);
    text-decoration: none;
    text-transform: capitalize;
}
.event-glance__tag:hover,
.event-glance__tag:focus {
    border-color: var(--townsy-primary);
    color: var(--townsy-primary);
}

.event-glance__actions {
    display: grid;
    gap: .5rem;
}
.event-glance__actions .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    font-weight: 600;
}
.event-glance__btn-outline {
    border: 1px solid var(--townsy-primary);
    border-radius: var(--townsy-radius);
    color: var(--townsy-primary);
    background: var(--townsy-white);
    padding: .55rem 1.4rem;
}
.event-glance__btn-outline:hover,
.event-glance__btn-outline:focus {
    background: var(--townsy-bg-light);
    border-color: var(--townsy-primary);
    color: var(--townsy-primary);
}
.event-glance__directions {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .4rem 0 0;
    font-weight: 600;
    color: var(--townsy-primary);
}

/* ---------- Venue, map and anything else TEC lists ---------- */

.tribe-events-single .tribe-events-event-meta {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
    margin: 0 0 2.5rem;
    padding: 2rem 0 0;
    border-top: 1px solid var(--townsy-border);
    background: none;
}
/* TEC draws its own rules here: a 1116px-wide ::before line that runs out
   of the column and across the event card, and a top border on the map.
   The section's border-top above is the only divider it needs. */
.tribe-events-single .tribe-events-event-meta::before,
.tribe-events-single .tribe-events-event-meta::after {
    content: none;
}
.tribe-events-single .tribe-events-meta-group-gmap {
    border-top: 0;
}
.tribe-events-single .tribe-events-meta-group {
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
    /* TEC's small-screen CSS moves the venue after the map with order:1,
       putting the map above its own heading. Keep source order. */
    order: 0;
}
.tribe-events-single .tribe-events-single-section-title {
    font-size: 1.5rem;
    font-weight: 700;
    text-transform: none;
    color: var(--townsy-primary);
    margin: 0 0 .75rem;
}
/* TEC's meta text is 14px #8e8e8e — about 3.3:1 on white, short of the
   4.5:1 WCAG AA minimum. */
.tribe-events-single .tribe-events-meta-list,
.tribe-events-single .tribe-events-meta-item,
.tribe-events-single .tribe-events-address {
    font-size: 1rem;
    line-height: 1.6;
    color: var(--townsy-text);
}
.tribe-events-single .tribe-events-meta-item a {
    color: var(--townsy-primary);
    font-weight: 600;
}
.tribe-events-single .tribe-events-venue-map {
    width: 100%;
    margin: 0;
}
.tribe-events-single .tribe-events-venue-map iframe {
    display: block;
    width: 100%;
    border-radius: var(--townsy-radius);
}

@media (min-width: 768px) {
    .tribe-events-single .tribe-events-event-meta {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
        align-items: start;
    }
}

/* ---------- Previous / next ---------- */

.tribe-events-single #tribe-events-footer {
    margin: 0;
    padding: 2rem 0 0;
    border-top: 1px solid var(--townsy-border);
}
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav li {
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
}
.tribe-events-single #tribe-events-footer .tribe-events-nav-next {
    text-align: right;
}
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav a {
    display: block;
    height: 100%;
    padding: 1rem 1.25rem;
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    font-weight: 600;
    color: var(--townsy-primary);
    text-decoration: none;
}
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav a:hover,
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav a:focus {
    border-color: var(--townsy-primary);
    background: var(--townsy-bg-light);
}
/* The nav slot stays in place when there is no previous or next event,
   so the other link keeps its side. */
.tribe-events-single #tribe-events-footer .tribe-events-sub-nav li:empty {
    visibility: hidden;
}

/* ---------- Wide screens: card becomes a sticky side column ---------- */

@media (min-width: 992px) {
    /* TEC sets overflow:hidden here to clear floats. A grid needs no
       clearing, and overflow:hidden would make this element the sticky
       card's scroll container, pinning it 94px down from the top. */
    .tribe-events-single .type-tribe_events {
        overflow: visible;
        display: grid;
        grid-template-columns: minmax(0, 1fr) 20rem;
        column-gap: 3rem;
        align-items: start;
    }
    .tribe-events-single .type-tribe_events > * {
        grid-column: 1;
    }
    .tribe-events-single .type-tribe_events > .event-glance {
        grid-column: 2;
        grid-row: 1 / span 20;
        position: sticky;
        top: calc(var(--townsy-header-height) + 1.5rem);
        margin: 0;
    }
}

/* =========================================================
   SEARCH RESULTS PAGE
   ========================================================= */

.search-term {
    color: var(--townsy-secondary);
}

/* Count + refine row */
.search-count {
    font-size: var(--townsy-text-sm);
    color: var(--townsy-text-muted);
}

.search-refine-form .form-control {
    border-color: var(--townsy-border);
    min-width: 220px;
}

/* Individual result card */
.search-result-card {
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--townsy-border);
}

.search-result-card:first-child {
    border-top: 1px solid var(--townsy-border);
}

.search-result-body {
    flex: 1 1 0;
    min-width: 0;
}

.search-result-type {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--townsy-label-color);
    background: var(--townsy-bg-light);
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    padding: 2px 8px;
    margin-bottom: .4rem;
}

.search-result-title {
    font-size: var(--townsy-text-xl);
    font-weight: 700;
    margin-bottom: .2rem;
    line-height: 1.3;
}

.search-result-title a {
    color: var(--townsy-primary);
    text-decoration: none;
}

.search-result-title a:hover {
    color: var(--townsy-primary-light);
    text-decoration: underline;
}

.search-result-path {
    font-size: var(--townsy-text-sm);
    color: var(--townsy-text-muted);
    margin-bottom: .4rem;
}

.search-result-excerpt {
    font-size: var(--townsy-text-base);
    color: var(--townsy-text);
    margin-bottom: 0;
    line-height: 1.55;
}

/* Optional thumbnail */
.search-result-thumb {
    flex: 0 0 90px;
    width: 90px;
    height: 70px;
    border-radius: var(--townsy-radius);
    overflow: hidden;
}

.search-result-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Pagination */
.search-pagination .page-numbers {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    height: 2.25rem;
    padding: 0 .6rem;
    border: 1px solid var(--townsy-border);
    border-radius: var(--townsy-radius);
    color: var(--townsy-primary);
    font-size: var(--townsy-text-sm);
    text-decoration: none;
    margin: 0 2px;
    transition: background .15s, color .15s;
}

.search-pagination .page-numbers:hover,
.search-pagination .page-numbers.current {
    background: var(--townsy-primary);
    color: var(--townsy-white);
    border-color: var(--townsy-primary);
}

/* No results state */
.search-no-results {
    padding: 3rem 0;
    color: var(--townsy-text-muted);
}

.search-no-results-icon {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: .35;
    display: block;
    text-align: left;
}

.search-no-results h2 {
    font-size: var(--townsy-h3-size);
    color: var(--townsy-text);
    margin-bottom: .75rem;
}

/* =========================================================
   SINGLE JOB LISTING
   ========================================================= */

.job-detail-row {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--townsy-border);
    font-size: var(--townsy-text-sm);
}

.job-detail-row:last-child {
    border-bottom: none;
}

.job-detail-label {
    font-weight: 600;
    color: var(--townsy-text-muted);
    min-width: 120px;
    flex-shrink: 0;
}

/* =========================================================
   SINGLE STAFF MEMBER — photo placeholder
   ========================================================= */

.staff-photo-placeholder {
    width: 100%;
    aspect-ratio: 1;
    max-height: 380px;
    background: var(--townsy-bg-light);
    border-radius: var(--townsy-radius);
    display: flex;
    align-items: center;
    justify-content: center;
}

.staff-photo-placeholder .bi {
    font-size: 6rem;
    color: var(--townsy-border);
}
