/*
Theme Name: SocietyPress
Theme URI: https://societypress.net
Author: Stricklin Development
Author URI: https://stricklindevelopment.com/
Description: A clean, readable theme for genealogical and historical societies.
             Designed for ease of use with large fonts, high contrast, and simple navigation.
Version: 1.5.86
Requires at least: 6.0
Tested up to: 6.9
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: societypress
Tags: genealogy, historical-society, membership, one-column, two-columns, custom-logo, custom-menu
*/

/* ============================================================================
   RESET & BASE
   WHY: Start from a consistent baseline across browsers. We use a minimal
   reset instead of a heavy framework — less code, faster load times.

   All colors, fonts, sizes, and widths now reference CSS custom properties
   defined in the :root block output by functions.php. This means the entire
   site's appearance can be changed from the Design settings tab without
   touching any CSS files.
   ============================================================================ */

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

html {
    /* WHY var(--sp-font-size-base): The base font size (default 18px) is
       controlled by the Design settings. "Compact" = 16px, "Comfortable" = 18px,
       "Large" = 20px. All rem-based sizes throughout the stylesheet scale
       proportionally when this changes. */
    font-size: var(--sp-font-size-base, 18px);
    scroll-behavior: smooth;
}

body {
    /* WHY var(--sp-font-body): The body font family is selectable from the
       Design tab. Defaults to the system font stack for maximum compatibility. */
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif);
    line-height: 1.7;
    color: #2d2d2d;
    background: #fff;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ============================================================================
   ACCESSIBILITY — SKIP NAVIGATION
   WHY: Keyboard and screen reader users need a way to bypass the header and
   nav and jump straight to the page content. Without this, they have to Tab
   through every nav link on every page load. This is a WCAG 2.1 Level A
   requirement (Success Criterion 2.4.1 — Bypass Blocks).

   The link is visually hidden off-screen until it receives keyboard focus,
   at which point it slides into view at the top of the page.
   ============================================================================ */

.skip-to-main {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
    z-index: 100000;
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    padding: 12px 24px;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    border-bottom-right-radius: 4px;
}

.skip-to-main:focus {
    position: fixed;
    top: 0;
    left: 0;
    width: auto;
    height: auto;
    outline: 2px solid #fff;
    outline-offset: -2px;
}

/* ============================================================================
   TYPOGRAPHY
   WHY: Clear hierarchy helps users scan pages quickly. Generous spacing
   between elements prevents that "wall of text" feeling.

   Heading sizes use calc() with --sp-font-scale so a single "heading scale"
   control in the Design tab proportionally adjusts all heading sizes.
   ============================================================================ */

h1, h2, h3, h4, h5, h6 {
    /* WHY var(--sp-color-primary): All headings use the primary brand color.
       This creates visual consistency and reinforces the society's identity. */
    color: var(--sp-color-primary, #1e3a5f);
    /* WHY var(--sp-font-heading): Headings can use a different font family
       than body text. "inherit" means they use the body font. */
    font-family: var(--sp-font-heading, inherit);
    line-height: 1.3;
    margin-bottom: 0.5em;
}

/* WHY calc() with --sp-font-scale: Instead of making Harold set each heading
   size individually, a single scale factor adjusts all of them proportionally.
   "Small" (0.85) makes headings more subtle, "Large" (1.15) makes them bolder. */
h1 { font-size: calc(2rem * var(--sp-font-scale, 1)); }
h2 { font-size: calc(1.6rem * var(--sp-font-scale, 1)); }
h3 { font-size: calc(1.3rem * var(--sp-font-scale, 1)); }
h4 { font-size: calc(1.1rem * var(--sp-font-scale, 1)); }

p {
    margin-bottom: 1em;
}

a {
    /* WHY var(--sp-color-primary-hover) for links: Links use the hover variant
       of the primary color so they're visually distinct from headings while
       still belonging to the same color family. */
    color: var(--sp-color-primary-hover, #2c5282);
    text-decoration: underline;
}

a:hover {
    color: var(--sp-color-primary, #1e3a5f);
}

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

/* ============================================================================
   LAYOUT
   WHY: Simple, centered layout with a comfortable reading width. Content
   wider than ~75 characters per line becomes hard to read.

   --sp-content-width controls the max-width of all content containers.
   "Narrow" = 900px, "Standard" = 1200px, "Wide" = 1400px.
   ============================================================================ */

.site {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.site-content {
    flex: 1;
    max-width: var(--sp-content-width, 1500px);
    margin: 0 auto;
    padding: 40px 20px;
    width: 100%;
}

/* Two-column layout for posts (content + sidebar) */
.content-area-with-sidebar {
    display: flex;
    gap: 40px;
}

.content-area-with-sidebar .main-content {
    flex: 1;
    min-width: 0; /* Prevent content from overflowing flex container */
}

.content-area-with-sidebar .widget-area {
    width: 300px;
    flex-shrink: 0;
}

/* Single-column layout for pages.
   WHY no max-width: .content-area-full is always nested inside .site-content
   (page.php, page-my-account.php, front-page.php, 404.php, and the plugin-
   rendered pages all wrap it that way), and .site-content already caps at
   --sp-content-width. Re-asserting the cap here was redundant and set a
   maintenance trap — any later attempt to make this container narrower than
   .site-content would have to fight the outer cap. */
.content-area-full {
    margin: 0 auto;
}

/* ============================================================================
   HEADER
   WHY: Simple, familiar layout — logo/title on the left, navigation on the
   right. Background color is controlled by --sp-color-header-bg so societies
   can match their brand without touching code.
   ============================================================================ */

.site-header {
    background: var(--sp-color-header-bg, #1e3a5f);
    color: var(--sp-color-header-text, #fff);
    padding: 0 20px;
    /* WHY box-shadow: the header's background pulls from Design settings.
       On dark colors, the edge between header and page is obvious. On
       light or white headers, the header bleeds into the white page body
       and the nav looks like it's floating mid-page with no container.
       A faint shadow draws a subtle separator that's visible against a
       white body but invisible against a dark one — works at every
       header color without special-casing. No layout shift (unlike a
       border-bottom, which would add a pixel). */
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
}

/* WHY max-width on the inner and not on .site-header: the header's
   background color (and the hairline shadow below it) should still
   span the full viewport so the page reads as a clean banded layout.
   But the nav, logo, and user menu inside should align with the
   content column below so the header feels like part of the page,
   not a disconnected ribbon. The inner matches --sp-content-width
   (same variable the body content uses). On narrower viewports the
   horizontal padding keeps the items from crowding the edges. */
/* WHY overflow: visible instead of hidden: The user dropdown menu renders
   absolutely positioned below the header. overflow:hidden would clip it.
   The original hidden was added to contain floats, but flexbox doesn't
   need that — all children are flex items already. */
.header-inner {
    max-width: var(--sp-content-width, 1500px);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 80px;
    padding: var(--sp-header-padding, 8px) 20px;
}

@media (min-width: 1025px) {
    .header-inner {
        padding: var(--sp-header-padding, 8px) 40px;
    }
}

@media (min-width: 1400px) {
    .header-inner {
        padding: var(--sp-header-padding, 8px) 60px;
    }
}

.site-branding {
    display: flex;
    align-items: center;
    gap: 12px;
}

.site-branding a {
    color: var(--sp-color-header-text, #fff);
    text-decoration: none;
}

.site-branding a:hover {
    opacity: 0.9;
}

/* WHY the variable: Settings → Design has a Logo Size field that saves, and the
   plugin emits it as --sp-logo-height, but this rule used to hardcode 75px — so
   the control did nothing at all and a society that wanted a bigger logo had no
   way to get one. The 75px stays as the fallback, which is what every site
   without the setting has always had. */
.custom-logo {
    max-height: var(--sp-logo-height, 75px);
    width: auto;
}

.site-title {
    font-family: var(--sp-font-heading, 'Playfair Display', Georgia, serif);
    font-size: 1.4rem;
    font-weight: 600;
    margin: 0;
    line-height: 1.2;
    letter-spacing: 0.01em;
}

.site-title a {
    color: var(--sp-color-header-text, #fff);
    text-decoration: none;
}

.site-description {
    font-size: 0.75rem;
    opacity: 0.8;
    margin: 0;
}

/* ============================================================================
   HEADER NAV AREA
   WHY: Wraps the primary nav and user menu together so they sit side by side
   in the header. The nav items flow left, the user menu anchors to the right.
   ============================================================================ */

/* WHY flex:1: The nav area fills all remaining space after the logo.
   Nav items sit flush left, .sp-nav-right items (Store, Contact, Join)
   push right via margin-left:auto on the first one. Search and Sign In
   follow naturally after the nav. */
.header-nav-area {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* ----------------------------------------------------------------------------
   STACKED HEADER — logo on its own row, navigation full width beneath it.

   WHY it exists: in the default single row the menu only gets whatever space
   the logo leaves, which for a society with a crest and a long name is not
   much. The usual outcome is shrinking the nav font until it fits, and past a
   certain point the items stop fitting at all and run underneath the logo. A
   society with real depth to show should not have to choose between its logo
   and its navigation, so the two get a row each.

   Desktop only. Below 1025px the nav is already a hamburger panel and the row
   is not contended, so stacking there would only add height.
---------------------------------------------------------------------------- */
@media (min-width: 1025px) {
    .site-header.sp-header-stacked .header-inner {
        flex-direction: column;
        /* stretch, not center: each row spans the header so the logo can sit
           against the left content edge rather than floating in the middle. */
        align-items: stretch;
        justify-content: center;
        /* Tight: the nav links carry their own vertical padding, so a gap here
           adds to that rather than replacing it and the menu drifts away from
           the logo. */
        gap: 0;
        /* Two rows cannot live inside a fixed single-row height. */
        height: auto;
        min-height: 0;
    }

    /* WHY display:block: the logo is an <img> inside an inline <a>, so it sits
       on the text baseline and carries descender space beneath it. That space
       is not margin or padding and no amount of tuning either one removes it —
       it is why the menu looked pushed down from the logo. */
    .site-header.sp-header-stacked .custom-logo-link,
    .site-header.sp-header-stacked .custom-logo {
        display: block;
    }

    /* Logo hard against the left content edge, matching how the rest of the
       page lines up. A centered logo above left-aligned content reads as a
       mistake even when it is deliberate. */
    .site-header.sp-header-stacked .site-branding {
        justify-content: flex-start;
    }

    /* The nav row spans the header rather than filling leftover space. */
    .site-header.sp-header-stacked .header-nav-area {
        flex: 0 0 auto;
        width: 100%;
        /* Pull the row up by most of the padding the links carry above their
           text, but not all of it. WHY not the full amount: a logo with a
           descending flourish — and a lot of society logos have one — ends up
           almost touching the menu. Three pixels of the padding are left in
           place so the two never collide.
           WHY not just reduce the padding itself: it is the click target.
           These sites are run and read by people for whom a smaller target is
           a real cost, and a few pixels of tidiness is not worth it. Moving
           the whole row leaves every target exactly the size it was. */
        margin-top: -7px;
    }

    /* WHY :not(.sp-user-menu): the signed-in user menu is ALSO a
       nav.main-navigation. Without the exclusion it takes flex:1 as well, the
       two split the row between them, and the user's name lands on top of the
       middle of the menu. The base nav rule below carries the same exclusion
       for the same reason. */
    .site-header.sp-header-stacked .main-navigation:not(.sp-user-menu) {
        flex: 1;
    }

    /* WHY the doubled class: child themes commonly set their own alignment on
       this list, and a child stylesheet loads after the parent — matching
       specificity would lose on source order alone.

       WHY centered rather than the space-between this once hardcoded: spreading
       the items edge to edge only reads as deliberate with a long menu. A
       society with six items got six links flung to the far corners with holes
       between them. Spreading is still available — Settings → Design → Menu
       Position — and the plugin writes the chosen value over this one.

       WHY nowrap: the row must stay one line; see the white-space note on the
       links below. */
    .site-header.sp-header-stacked .main-navigation.main-navigation:not(.sp-user-menu) > ul {
        justify-content: center;
        flex-wrap: nowrap;
        width: 100%;
    }
}

/* ============================================================================
   NAVIGATION
   WHY: Horizontal nav in the header is the most familiar pattern for our
   users. Large click targets (padding) make it easier for everyone.
   ============================================================================ */

/* WHY > ul (direct child only): The parent theme's nav is single-level, but
   some child themes use multi-level dropdowns. If we apply display:flex to
   ALL ul elements (.main-navigation ul), sub-menus inherit flex layout and
   their display:none / display:block toggle can conflict with the flex
   context. Scoping to > ul keeps the top-level menu horizontal without
   affecting nested sub-menu lists that child themes style independently. */
/* WHY flex:1 on nav and ul: The primary nav must stretch to fill the full
   header width so margin-left:auto on right-aligned items (Store, Contact,
   Join) can push them to the right edge. The :not(.sp-user-menu) exclusion
   is critical — the Sign In menu is also nav.main-navigation, and giving
   it flex:1 too would split the space 50/50, killing the gap. */
/* WHY display:flex here: Without it, the nav is display:block — it gets
   flex-sized by header-nav-area, but internally the ul's width:100% resolves
   against the nav's content-based width, not its flex-assigned width.
   Making the nav itself a flex container ensures the ul stretches fully,
   giving margin-left:auto on .sp-nav-right items room to push right.
   WHY desktop-only: On mobile (<= 1024px), the nav toggles between
   display:none and display:block via .sp-nav-open. This rule must not
   interfere with that toggle. */
@media (min-width: 1281px) {
    .main-navigation:not(.sp-user-menu) {
        flex: 1;
        display: flex;
        min-width: 0;
    }
}


.main-navigation > ul {
    list-style: none;
    display: flex;
    gap: 4px;
    width: 100%;
}

/* Sub-menus inside child themes need list-style reset too */
.main-navigation ul {
    list-style: none;
}

.main-navigation a {
    display: block;
    padding: 10px 18px;
    /* WHY nowrap: the nav is a flex row that does not wrap, so when the items
       no longer fit the browser shrinks them and the label inside each one
       breaks onto a second line — a one-line menu silently becomes a two-line
       menu. Browsers disagree about how far a flex item may shrink, which is
       why the same menu at the same window width sat on one line in Firefox
       and two in Safari. Holding each label on one line makes the layout the
       same everywhere. */
    white-space: nowrap;
    color: var(--sp-color-header-text, #fff);
    text-decoration: none;
    font-size: var(--sp-nav-font-size, 0.85rem);
    font-weight: var(--sp-nav-font-weight, 500);
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, sans-serif);
    letter-spacing: 0.02em;
    border-radius: 4px;
    transition: background 0.2s ease, color 0.2s ease;
}

/* WHY no background tint: it was rgba(255,255,255,0.12), which is invisible
   on a dark header and a pale smudge on a light one — every society running a
   cream or white header got a box around whichever page they were on that no
   setting could turn off. An underline reads the same way on any background,
   and the current page keeps the colour it already had. */
.main-navigation a:hover,
.main-navigation a:focus-visible {
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* WHY explicit focus indicator: the browser default focus ring is a thin
   blue outline that fails WCAG 1.4.11 non-text contrast against the dark
   --sp-color-nav-bg. A white 2px outline with offset reliably stands out
   on every nav background a society might choose, and the background tint
   on focus matches the hover state so the active item still looks active
   when focused. */
.main-navigation a:focus,
.main-navigation a:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
    background: rgba(255, 255, 255, 0.12);
}

/* User account menu — "Charles" / "Log Out" etc. Sits alongside the main
   nav in the header, not inside it, so .main-navigation rules don't
   reach it. WHY we set both :link and :visited: the logout URL carries
   a nonce that changes every page load, so it's never "visited" in the
   browser's history; the my-account URL is stable and therefore IS. On
   a light header, the browser's default purple-ish visited color makes
   the two user-menu links look mismatched. Pinning both to the header
   text color keeps them consistent. */
.sp-user-nav-link,
.sp-user-nav-link:link,
.sp-user-nav-link:visited {
    display: inline-block;
    padding: 10px 14px;
    color: var(--sp-color-header-text, #fff);
    text-decoration: none;
    /* WHY font-family is explicit: without it, sp-user-nav-link inherits
       from an upstream rule that's serif on some themes, which makes
       "Charles" and "Log Out" look like a different typeface from the
       main nav. Pin it to the same body-font var the main nav uses. */
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, sans-serif);
    font-size: var(--sp-nav-font-size, 0.85rem);
    font-weight: var(--sp-nav-font-weight, 500);
    /* WHY line-height: 1: lets the optical center of the text sit at the
       flex-item center, so an adjacent avatar aligns to the visual
       middle of the word rather than to the line-box center (which
       includes descender space the word "Charles" doesn't use). */
    line-height: 1;
    letter-spacing: 0.02em;
    border-radius: 4px;
    transition: background 0.2s ease, color 0.2s ease;
}

.sp-user-nav-link:hover,
.sp-user-nav-link:focus {
    background: rgba(128, 128, 128, 0.12);
    color: var(--sp-color-header-text, #fff);
}

.sp-user-nav-link:focus-visible {
    outline: 2px solid var(--sp-color-header-text, #fff);
    outline-offset: 2px;
}

/* Avatar-with-name variant — small round photo to the left of the
   member's name. Inherits link color/size from .sp-user-nav-link.
   !important on display because the base .sp-user-nav-link rule (which
   includes :link/:visited pseudo-classes, bumping its specificity) was
   winning the cascade and keeping display: inline-block. That stacked
   the avatar above the name instead of beside it. Forcing the flex
   layout here removes any possibility of another rule overriding it. */
.sp-user-nav-link--with-avatar {
    display: inline-flex !important;
    align-items: center;
    gap: 12px;
}

.sp-user-avatar {
    /* display: block removes the inline-baseline gap that pushes <img>
       slightly off-center from adjacent text. flex-shrink: 0 keeps it
       a perfect circle even if the header runs out of room. */
    display: block;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

/* WHY: The "Join" link is the primary CTA — it should stand out from
   regular nav items. We target it by class (.menu-item-join) which
   Harold can set by adding a CSS class to the menu item, or we
   detect it by URL (the Join page). */
.main-navigation .menu-item-join > a,
.main-navigation .sp-nav-cta > a {
    background: var(--sp-color-accent, #454FBF);
    color: #fff;
    border-radius: 4px;
    font-weight: 600;
}

.main-navigation .menu-item-join > a:hover,
.main-navigation .sp-nav-cta > a:hover {
    opacity: 0.9;
    background: var(--sp-color-accent, #454FBF);
}

/* Renewal CTA — visually distinct from the Join CTA so it reads as
   "action needed" rather than "optional." Uses --sp-color-warning with a
   warm amber fallback; a society can override the variable in Design
   settings (or a child theme) to match their palette. A subtle pulse
   draws the eye without being obnoxious. */
.main-navigation .sp-show-when-expiring > a {
    background: var(--sp-color-warning, #A0560F);
    color: #fff;
    border-radius: 4px;
    font-weight: 600;
    box-shadow: 0 0 0 0 rgba(201, 123, 42, 0.5);
    animation: sp-renew-pulse 2.4s ease-out infinite;
}

.main-navigation .sp-show-when-expiring > a:hover {
    opacity: 0.92;
    background: var(--sp-color-warning, #A0560F);
    animation-play-state: paused;
}

@keyframes sp-renew-pulse {
    0%   { box-shadow: 0 0 0 0   rgba(201, 123, 42, 0.55); }
    70%  { box-shadow: 0 0 0 10px rgba(201, 123, 42, 0);    }
    100% { box-shadow: 0 0 0 0   rgba(201, 123, 42, 0);    }
}

/* Respect the user's reduced-motion preference — accessibility first */
@media (prefers-reduced-motion: reduce) {
    .main-navigation .sp-show-when-expiring > a {
        animation: none;
    }
}

/* WHY: Secondary nav items (Store, Contact, Join) push to the right edge
   of the header bar, matching the Ancestry pattern — primary nav flush left
   next to the logo, utility/secondary items flush right next to Sign In.
   All .sp-nav-right items get margin-left:auto (which absorbs remaining
   space), then the sibling combinator resets subsequent ones to 0 so only
   the first one creates the gap. !important overrides any gap/margin
   reset from the flex container. */
.main-navigation > ul > li.sp-nav-right {
    margin-left: auto !important;
}
.main-navigation > ul > li.sp-nav-right ~ li.sp-nav-right {
    margin-left: 0 !important;
}

/* ============================================================================
   SUB-MENU DROPDOWNS
   WHY: WordPress outputs nested <ul class="sub-menu"> for child menu items.
   On desktop, sub-menus appear as dropdown panels below the parent item on
   hover/focus. The parent li gets .menu-item-has-children from WP core.
   ============================================================================ */

/* Position the parent li so the sub-menu anchors to it */
.main-navigation > ul > li.menu-item-has-children {
    position: relative;
}

/* Dropdown caret on parent items — indicates a sub-menu is available */
.main-navigation > ul > li.menu-item-has-children > a::after {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid currentColor;
    margin-left: 6px;
    vertical-align: middle;
    opacity: 0.7;
    transition: transform 0.2s ease;
}

/* Rotate caret when sub-menu is open */
.main-navigation > ul > li.menu-item-has-children.sp-submenu-open > a::after {
    transform: rotate(180deg);
}

/* The sub-menu itself — hidden by default, drops below the parent */
.main-navigation .sub-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background: var(--sp-color-nav-bg, var(--sp-color-header-bg, #1e3a5f));
    border-top: 3px solid var(--sp-color-accent, rgba(255, 255, 255, 0.2));
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    border-radius: 0 0 4px 4px;
    padding: 4px 0;
    z-index: 1000;
    list-style: none;
}

/* Show on hover (desktop) and when JS adds .sp-submenu-open */
.main-navigation > ul > li.menu-item-has-children:hover > .sub-menu,
.main-navigation > ul > li.menu-item-has-children.sp-submenu-open > .sub-menu {
    display: block;
}

/* Sub-menu links — full width, stacked vertically */
.main-navigation .sub-menu a {
    padding: 10px 20px;
    font-size: var(--sp-nav-font-size, 0.85rem);
    white-space: nowrap;
    border-radius: 0;
}

.main-navigation .sub-menu a:hover,
.main-navigation .sub-menu .current-menu-item a {
    background: rgba(255, 255, 255, 0.12);
}

/* Sub-menu item dividers */
.main-navigation .sub-menu li + li {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* ----------------------------------------------------------------------------
   NESTED (LEVEL 2) SUB-MENUS
   WHY: WordPress nav menus support arbitrary depth. We enabled depth: 3 so
   Resources → Library → Catalog-style nesting works for societies with deep
   information architectures. Level-2 flyouts drop to the right of their
   parent rather than cascading further down, which would otherwise run
   off the viewport.
   ---------------------------------------------------------------------------- */

/* Position each nested parent so its flyout anchors to it */
.main-navigation .sub-menu li.menu-item-has-children {
    position: relative;
}

/* Level-2 caret: right-pointing triangle, sitting at the end of the label */
.main-navigation .sub-menu li.menu-item-has-children > a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
}

.main-navigation .sub-menu li.menu-item-has-children > a::after {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 4px solid currentColor;
    opacity: 0.7;
    transition: transform 0.2s ease;
    flex-shrink: 0;
}

/* Flyout panel — anchored to the right edge of the parent item */
.main-navigation .sub-menu .sub-menu {
    top: -4px;
    left: 100%;
    border-top: none;
    border-left: 3px solid var(--sp-color-accent, rgba(255, 255, 255, 0.2));
    border-radius: 0 4px 4px 0;
}

/* The same panel, opening leftward instead.
   WHY: flyouts chain rightward, so a menu four or five levels deep eventually
   runs past the right edge of the window and the deepest level — the one the
   visitor was reaching for — is the part that ends up off screen. theme.js
   measures each panel as it opens and sets this class when there is no room
   on the right; only the browser knows how wide the window is, so the
   measurement has to happen there. Nothing about the level-2 flyout changes
   on a wide screen. */
.main-navigation .sub-menu .sub-menu.sp-flyout-left {
    left: auto;
    right: 100%;
    border-left: none;
    border-right: 3px solid var(--sp-color-accent, rgba(255, 255, 255, 0.2));
    border-radius: 4px 0 0 4px;
}

/* Reveal on hover or when JS toggles sp-submenu-open */
.main-navigation .sub-menu li.menu-item-has-children:hover > .sub-menu,
.main-navigation .sub-menu li.menu-item-has-children:focus-within > .sub-menu,
.main-navigation .sub-menu li.menu-item-has-children.sp-submenu-open > .sub-menu {
    display: block;
}

/* Rotate caret when open (tap-toggled on mobile) */
.main-navigation .sub-menu li.menu-item-has-children.sp-submenu-open > a::after {
    transform: rotate(90deg);
}

/* Open top-level dropdowns on keyboard focus too (accessibility) */
.main-navigation > ul > li.menu-item-has-children:focus-within > .sub-menu {
    display: block;
}

/* Drop down caret button — added by theme.js next to every parent item.
   WHY it is hidden here: on desktop, hovering a parent already reveals its
   drop down and clicking the name goes to the page, so the caret has no job.
   It earns its place only in the mobile panel, where there is no hover and
   the two actions have to be told apart. The breakpoint below turns it on. */
.sp-submenu-toggle {
    display: none;
}

/* ============================================================================
   HAMBURGER MENU BUTTON (MOBILE)
   WHY: On screens below 768px the horizontal nav won't fit. We hide the nav
   and show a hamburger icon instead. The button is always in the DOM but
   hidden on desktop via display:none. Below 768px, CSS shows it and JS
   toggles the sp-nav-open class to reveal/hide the mobile nav panel.
   ============================================================================ */

.sp-hamburger {
    display: none; /* Hidden on desktop — only visible below 768px */
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px;
    min-width: 44px;  /* 44x44 minimum touch target (WCAG 2.5.5) */
    min-height: 44px;
    z-index: 1001;
}

.sp-hamburger:focus-visible {
    outline: 2px solid var(--sp-color-header-text, #fff);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Three horizontal bars that form the hamburger icon. Bar height (3px) and
   margin (5px) determine the icon's total height. The transition properties
   enable the smooth X animation when the menu opens. */
.sp-hamburger-bar {
    display: block;
    width: 26px;
    height: 3px;
    background: var(--sp-color-header-text, #fff);
    margin: 5px 0;
    border-radius: 2px;
    transition: transform 0.3s ease, opacity 0.3s ease;
}

/* X animation when menu is open — the top bar rotates down, the middle bar
   fades out, and the bottom bar rotates up. The translateY values (8px) are
   calculated from bar height (3px) + margin (5px) = 8px offset to bring the
   top and bottom bars to the center position before rotating. */
.sp-hamburger.is-active .sp-hamburger-bar:nth-child(1) {
    transform: translateY(8px) rotate(45deg);
}

.sp-hamburger.is-active .sp-hamburger-bar:nth-child(2) {
    opacity: 0;
}

.sp-hamburger.is-active .sp-hamburger-bar:nth-child(3) {
    transform: translateY(-8px) rotate(-45deg);
}

/* ============================================================================
   HEADER TOP BAR
   WHY: A slim utility strip above the main header row. Social media icons
   sit here, flush-right. Keeps them visible without crowding the nav,
   search, and user menu below. The bar inherits the header background so
   it blends seamlessly — child themes can override for a distinct look.
   ============================================================================ */

.header-top-bar {
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.header-top-bar-inner {
    max-width: var(--sp-content-width, 1500px);
    margin: 0 auto;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 4px 0;
}


/* ============================================================================
   SOCIAL MEDIA ICONS
   WHY: Small icon links to the society's social media profiles. Displayed
   in the header top bar, flush-right. Icons inherit currentColor so they
   match the header text color.
   ============================================================================ */

.sp-social-icons {
    display: flex;
    align-items: center;
    gap: 4px;
}

.sp-social-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;   /* 44x44 minimum touch target (WCAG 2.5.5) */
    height: 44px;
    border-radius: 50%;
    color: var(--sp-color-header-text, #fff);
    opacity: 0.7;
    transition: opacity 0.2s ease, background 0.2s ease;
    text-decoration: none;
}

.sp-social-icon:hover {
    opacity: 1;
    background: rgba(255, 255, 255, 0.15);
}

/* ============================================================================
   HEADER SEARCH FIELD
   WHY: A persistent search field in the header lets members search across
   the entire site (events, library, members, newsletters, pages) from any
   page. Compact on desktop (~180px, expands on focus), hidden on mobile
   where the hamburger menu provides the search field instead.
   ============================================================================ */

/* Search wrapper — holds the toggle button and the expandable form */
.sp-header-search-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

/* WHY hidden by default: When the admin adds a "Search" page to the nav
   menu, the magnifying glass toggle is redundant and creates a visual gap.
   The search wrap is still available for child themes that want it. */
.sp-header-search-wrap:not(.sp-search-open) {
    display: none;
}

/* Toggle button — the magnifying glass icon that opens/closes the search */
.sp-search-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px;
    min-width: 44px;   /* 44x44 minimum touch target (WCAG 2.5.5) */
    min-height: 44px;
    color: rgba(255, 255, 255, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease;
    border-radius: 50%;
}
.sp-search-toggle:hover {
    color: var(--sp-color-header-text, #fff);
    background: rgba(255, 255, 255, 0.1);
}

.sp-search-toggle:focus {
    outline: 2px solid rgba(255, 255, 255, 0.8);
    outline-offset: 2px;
}

/* Search form — hidden by default, slides open from the right */
.sp-header-search {
    display: none; /* JS toggles this to flex */
    align-items: center;
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 100;
    animation: sp-search-slide-in 0.2s ease-out;
}

/* WHY the open class: JS adds this when the toggle is clicked.
   Using a class (not :focus-within) gives us explicit control over
   open/close state — clicking away closes it via a document listener. */
.sp-header-search-wrap.sp-search-open .sp-header-search {
    display: flex;
}
.sp-header-search-wrap.sp-search-open .sp-search-toggle {
    /* Hide the toggle when search is open — the form has its own icon */
    display: none;
}

@keyframes sp-search-slide-in {
    from { opacity: 0; transform: translateY(-50%) translateX(10px); }
    to   { opacity: 1; transform: translateY(-50%) translateX(0); }
}

.sp-header-search input[type="text"] {
    width: 240px;
    padding: 8px 36px 8px 14px; /* Right padding leaves room for the button */
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 20px;
    background: rgba(255, 255, 255, 0.15);
    color: var(--sp-color-header-text, #fff);
    font-size: 0.85rem;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.sp-header-search input[type="text"]::placeholder {
    color: rgba(255, 255, 255, 0.78); /* 0.6 read at ~3.8:1 on the dark header; 0.78 clears AA */
}

/* WHY solid white: rgba(255,255,255,0.7) border and subtle background
   shift didn't meet the 3:1 minimum contrast ratio for focus indicators
   against the dark header. Solid white ring is unmistakable. The browser
   default focus outline is suppressed only here (in the focus rule, not
   the base state) so it never silently disappears for keyboard users. */
.sp-header-search input[type="text"]:focus {
    outline: none;
    box-shadow: 0 0 0 2px #fff;
    border-color: #fff;
    background: rgba(255, 255, 255, 0.2);
}

/* Magnifying glass submit button — positioned inside the input */
.sp-header-search button[type="submit"] {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 8px;
    color: rgba(255, 255, 255, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease;
}

.sp-header-search button[type="submit"]:hover {
    color: var(--sp-color-header-text, #fff);
}

/* ============================================================================
   USER ACCOUNT MENU
   WHY: Replaces the WordPress admin bar with a clean dropdown in the header.
   Shows the user's avatar and name at a glance, with a dropdown for
   profile, photo, info, dashboard (admins only), and logout.

   Pure CSS dropdown using :hover and :focus-within — no JavaScript needed.
   The :focus-within ensures keyboard users can tab into the dropdown and
   it stays open while they navigate the items.
   ============================================================================ */

.sp-user-menu {
    position: relative;
}

/* Account links the plugin adds to the end of the primary menu. They belong to
   the phone menu panel only, so they stay hidden until the panel opens; on a
   wide screen the header account menu already does this job. */
.sp-nav-account {
    display: none;
}

.sp-nav-open .sp-nav-account {
    display: block;
}

.sp-nav-open .sp-nav-account-first {
    border-top: 2px solid rgba(127, 127, 127, 0.4);
}

/* The dropdown anchors to the li inside the user menu nav */
.sp-user-menu li {
    position: relative;
}

/* Log In / profile name link — styled identically to nav menu items */
.sp-user-login-link {
    display: block;
    padding: 10px 18px;
    color: var(--sp-color-header-text, #fff);
    text-decoration: none;
    font-size: var(--sp-nav-font-size, 0.85rem);
    font-weight: var(--sp-nav-font-weight, 500);
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, sans-serif);
    letter-spacing: 0.02em;
    border-radius: 4px;
    transition: background 0.2s ease, color 0.2s ease;
    white-space: nowrap;
}

.sp-user-login-link:hover {
    background: rgba(255, 255, 255, 0.15);
    color: var(--sp-color-header-text, #fff);
}

/* The trigger — avatar + name + caret.

   WHY no background and no border: the old rule filled it with
   rgba(255,255,255,0.1) and outlined it in rgba(255,255,255,0.2), which only
   works on a dark header. Every society running a light header — cream, white,
   pale anything — got a ghost box floating around the member's name that no
   setting could turn off. The member's name is a menu item like Home or
   Events, so it is drawn like one.

   WHY the 2px lift: with the padding gone the name and photo centre on the
   line box, which includes descender space the word does not use. Two pixels
   puts them on the optical middle of the menu instead. */
.sp-user-trigger {
    position: relative;
    top: -2px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--sp-color-header-text, #fff);
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
    transition: opacity 0.2s ease;
    white-space: nowrap;
}

/* WHY opacity and not a background: a hover tint has to be painted in a colour
   that reads on the header, and SocietyPress does not know what colour that
   is — each of the five child themes picks its own. Fading works on any of
   them. */
.sp-user-trigger:hover {
    opacity: 0.7;
}

/* Small downward caret */
.sp-user-caret {
    font-size: 0.7rem;
    opacity: 0.7;
    margin-left: 2px;
}

/* ------- Dropdown panel ------- */

.sp-user-dropdown {
    /*
        WHY visibility + opacity instead of display:none: This lets us
        animate the dropdown appearing (opacity transition) while still
        keeping it out of the tab order when closed (visibility:hidden).
    */
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 6px;
    min-width: 200px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    padding: 6px 0;
    visibility: hidden;
    opacity: 0;
    transform: translateY(-4px);
    transition: all 0.15s ease;
    z-index: 9999;
}

/*
    WHY both :hover and :focus-within:
    - :hover handles mouse users
    - :focus-within handles keyboard users (when tabbing through dropdown items)
    Both keep the dropdown open while the user is interacting with it.
*/
.sp-user-menu:hover .sp-user-dropdown,
.sp-user-menu:focus-within .sp-user-dropdown,
.sp-user-menu.sp-user-open .sp-user-dropdown {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

/* Update aria-expanded visually when dropdown is showing */
.sp-user-menu:hover .sp-user-trigger,
.sp-user-menu:focus-within .sp-user-trigger,
.sp-user-menu.sp-user-open .sp-user-trigger {
    background: rgba(255, 255, 255, 0.25);
}

/* Individual dropdown items.
   WHY the !important overrides: sp_user_menu() outputs items inside a
   nav.main-navigation wrapper (so the trigger link matches nav font rendering
   exactly). That means .main-navigation a rules inherit to these items,
   including color: var(--sp-color-header-text) which is usually white.
   We force the dropdown items to render dark on the white dropdown background. */
.sp-user-dropdown-item,
.main-navigation .sp-user-dropdown-item {
    display: flex !important;
    align-items: center;
    gap: 10px;
    padding: 10px 16px !important;
    color: #333 !important;
    text-decoration: none;
    font-size: 0.85rem !important;
    font-weight: 500 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    transition: background 0.15s ease;
    white-space: nowrap;
    border-radius: 0 !important;
}

.sp-user-dropdown-item:hover,
.sp-user-dropdown-item:focus,
.main-navigation .sp-user-dropdown-item:hover,
.main-navigation .sp-user-dropdown-item:focus {
    background: #f0f4f8 !important;
    color: var(--sp-color-primary, #1e3a5f) !important;
}

/* Dashicon styling inside dropdown items */
.sp-user-dropdown-icon {
    font-size: 16px;
    width: 20px;
    height: 20px;
    line-height: 20px;
    text-align: center;
    color: #6b7280;
}

.sp-user-dropdown-item:hover .sp-user-dropdown-icon {
    color: var(--sp-color-primary, #1e3a5f);
}

/* Divider line between menu groups */
.sp-user-dropdown-divider {
    height: 1px;
    background: #e9ecef;
    margin: 4px 12px;
}

/* Logout item — subtle red on hover to indicate destructive action */
.sp-user-dropdown-item--logout:hover,
.main-navigation .sp-user-dropdown-item--logout:hover {
    background: #fef2f2 !important;
    color: #b91c1c !important;
}

.sp-user-dropdown-item--logout:hover .sp-user-dropdown-icon {
    color: #b91c1c;
}

/* ============================================================================
   CONTENT — Posts & Pages
   ============================================================================ */

.entry-header {
    margin-bottom: 32px;
}

.entry-title {
    font-family: var(--sp-font-heading, 'Playfair Display', Georgia, serif);
    font-size: calc(2.2rem * var(--sp-font-scale, 1));
    font-weight: 500;
    margin-bottom: 10px;
    letter-spacing: -0.01em;
    line-height: 1.2;
}

.entry-title a {
    color: var(--sp-color-primary, #1e3a5f);
    text-decoration: none;
    transition: color 0.2s ease;
}

.entry-title a:hover {
    color: var(--sp-color-primary-hover, #2c5282);
}

.entry-meta {
    font-size: 0.8rem;
    color: #6b7280;
    margin-bottom: 16px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.entry-content {
    margin-bottom: 40px;
    font-size: 1rem;
    line-height: 1.8;
}

/* Give content elements consistent vertical rhythm */
.entry-content > * + * {
    margin-top: 1.2em;
}

.entry-content ul,
.entry-content ol {
    padding-left: 1.5em;
}

.entry-content blockquote {
    border-left: 4px solid var(--sp-color-accent, #454FBF);
    padding: 16px 24px;
    margin: 2em 0;
    background: #f8f9fb;
    font-style: italic;
    font-size: 1.05rem;
    color: #444;
    border-radius: 0 4px 4px 0;
}

/* "Read more" link styling */
.read-more {
    display: inline-block;
    margin-top: 12px;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sp-color-primary, #1e3a5f);
    text-decoration: none;
    transition: color 0.2s ease;
}

.read-more:hover {
    color: var(--sp-color-accent, #454FBF);
}

/* Post separator in archive/index views */
article.post {
    padding-bottom: 40px;
    margin-bottom: 40px;
    border-bottom: 1px solid #eef0f2;
}

article.post:last-child {
    border-bottom: none;
}

/* Featured images */
.post-thumbnail {
    margin-bottom: 24px;
    border-radius: 8px;
    overflow: hidden;
}

.post-thumbnail img {
    display: block;
    width: 100%;
    transition: transform 0.3s ease;
}

.post-thumbnail:hover img {
    transform: scale(1.02);
}

/* ============================================================================
   SIDEBAR / WIDGETS
   ============================================================================ */

.widget-area .widget {
    margin-bottom: 30px;
    padding: 20px;
    background: #f8f9fa;
    border-radius: 8px;
}

.widget-area .widget-title {
    font-size: 1rem;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--sp-color-primary, #1e3a5f);
}

.widget-area .widget ul {
    list-style: none;
}

.widget-area .widget li {
    padding: 6px 0;
    border-bottom: 1px solid #e9ecef;
}

.widget-area .widget li:last-child {
    border-bottom: none;
}

/* ============================================================================
   PAGINATION
   ============================================================================ */

.pagination {
    margin-top: 30px;
    display: flex;
    justify-content: center;
    gap: 8px;
}

.pagination a,
.pagination span {
    display: inline-block;
    padding: 8px 16px;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
}

.pagination a:hover {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    border-color: var(--sp-color-primary, #1e3a5f);
}

.pagination .current {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    border-color: var(--sp-color-primary, #1e3a5f);
}

/* ============================================================================
   FOOTER
   WHY: Simple footer with copyright. Background color mirrors the header
   for a cohesive look — both controlled by Design settings.
   ============================================================================ */

.site-footer {
    background: var(--sp-color-footer-bg, #1e3a5f);
    color: var(--sp-color-footer-text, #fff);
    padding: 0;
    font-size: 0.85rem;
}

.footer-inner {
    max-width: var(--sp-content-width, 1500px);
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1.2fr 1fr 1fr;
    gap: 40px;
    padding: 50px 20px 40px;
}

/* The last column sits against the right margin.

   WHY: the columns are sized in fractions, so they always span the full width
   of the footer — but their text does not. A column of short links, set on a
   wide screen, fills perhaps a fifth of the space it has been given and hugs
   its left edge, leaving the footer anchored at the left margin and trailing
   off into nothing at the right. Turning the last column's text around puts
   content on both margins, which is what makes a footer read as deliberate
   rather than as a layout that ran out of things to say.

   WHY only above 1024px: at 769-1024 the footer drops to two columns, the
   third wraps onto a row of its own, and the rule further down deliberately
   centres it there; below 769 everything stacks and the whole footer centres.
   In both of those the last column is no longer at the right-hand edge, so
   pushing its text to the right would point it at nothing. This belongs to the
   full three-column layout only. */
@media screen and (min-width: 1025px) {
    .footer-inner > .footer-col:last-child {
        text-align: right;
    }

    /* Flex and grid children do not take alignment from text-align, so the two
       things inside a footer column that are not plain text need saying
       separately: the social icon row, and an affiliation row placed in this
       column by Website → Affiliations. */
    .footer-inner > .footer-col:last-child .sp-affiliations-list,
    .footer-inner > .footer-col:last-child .sp-social-icons {
        justify-content: flex-end;
    }
}

.footer-heading {
    font-family: var(--sp-font-heading, 'Playfair Display', Georgia, serif);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--sp-color-footer-text, #fff);
    margin: 0 0 16px 0;
    letter-spacing: 0.02em;
}

.footer-text {
    color: var(--sp-color-footer-text, rgba(255, 255, 255, 0.8));
    line-height: 1.7;
    margin: 0 0 6px 0;
    font-size: 0.9rem;
}

.footer-tagline {
    margin-top: 12px;
    font-style: italic;
    opacity: 0.7;
}

.site-footer a {
    color: var(--sp-color-footer-link, rgba(255, 255, 255, 0.85));
    text-decoration: none;
    transition: color 0.2s ease;
}

.site-footer a:hover {
    color: #fff;
    text-decoration: underline;
}

/* Footer navigation — vertical link list */
.footer-nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-nav li {
    margin-bottom: 8px;
}

.footer-nav a {
    font-size: 0.9rem;
    color: var(--sp-color-footer-link, rgba(255, 255, 255, 0.85));
    text-decoration: none;
    transition: color 0.2s ease;
}

.footer-nav a:hover {
    color: #fff;
}

/* Affiliation logos — the bodies the society belongs to.

   WHY the logos get a white pill behind them: affiliation marks arrive as
   whatever file the parent organization publishes, and most are dark artwork
   on a transparent background. Dropped straight onto a navy footer, half of
   them vanish. A light plate means an administrator can use the file they were
   given without opening an image editor, which is the difference between this
   feature working and not.

   Sizing is by max-height rather than width so logos of wildly different
   proportions — a tall crest next to a wide wordmark — end up looking like
   they belong on the same row. */
.sp-affiliations {
    padding: 24px 20px 4px;
    text-align: center;
}

.sp-affiliations-heading {
    margin: 0 0 14px;
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    opacity: 0.75;
}

.sp-affiliations-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 16px;
}

.sp-affiliation {
    margin: 0;
    padding: 0;
}

.sp-affiliation img {
    display: block;
    max-height: 56px;
    width: auto;
    max-width: 190px;
    background: #fff;
    border-radius: 4px;
    padding: 8px 12px;
}

/* The link is the only interactive thing in this row, so it carries the hover
   and focus treatment rather than the image inside it. */
.sp-affiliation-link {
    display: block;
    text-decoration: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.sp-affiliation-link:hover,
.sp-affiliation-link:focus-visible {
    opacity: 0.85;
    transform: translateY(-2px);
}

.sp-affiliation-link:focus-visible {
    outline: 2px solid var(--sp-color-footer-link, #fff);
    outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
    .sp-affiliation-link {
        transition: none;
    }
    .sp-affiliation-link:hover,
    .sp-affiliation-link:focus-visible {
        transform: none;
    }
}

@media (max-width: 480px) {
    .sp-affiliation img {
        max-height: 44px;
        max-width: 140px;
    }
}

/* Footer bottom bar — copyright line */
.footer-bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    text-align: center;
    padding: 20px;
    font-size: 0.8rem;
    opacity: 0.7;
}

.footer-bottom p {
    margin: 0;
}

.footer-powered-by {
    margin-top: 4px;
    font-size: 0.75rem;
    opacity: 0.6;
}

.footer-powered-by a {
    color: inherit;
    text-decoration: none;
}

.footer-powered-by a:hover {
    text-decoration: underline;
}

/* Footer custom content and images */
.footer-custom-content {
    font-size: inherit;
    line-height: 1.6;
}

.footer-images {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
}

.footer-images img.footer-image {
    max-height: 60px;
    width: auto;
    opacity: 0.85;
    transition: opacity 0.2s;
}

.footer-images img.footer-image:hover {
    opacity: 1;
}

/* Responsive: stack columns on mobile */
@media screen and (max-width: 768px) {
    .footer-inner {
        grid-template-columns: 1fr;
        gap: 30px;
        padding: 40px 20px 30px;
        text-align: center;
    }
}

@media screen and (min-width: 769px) and (max-width: 1024px) {
    .footer-inner {
        grid-template-columns: 1fr 1fr;
    }
    .footer-col-social {
        grid-column: 1 / -1;
        text-align: center;
    }
}

/* ============================================================================
   FRONT PAGE HERO
   WHY: A full-viewport cinematic hero is the first thing visitors see. It
   needs to feel polished and intentional — this is the "wow" moment.
   Video backgrounds, image backgrounds, and a gradient fallback are all
   supported. The overlay ensures text is always readable regardless of
   the background media. All values are configurable from Design settings.
   ============================================================================ */

.sp-front-hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    /* WHY negative margin: The hero needs to break out of the site-content
       container and go edge-to-edge. The header sits above it; the hero
       is the first thing inside the main page flow. */
    margin-top: 0;
}

/* Height variants — fullscreen is the default, others available via settings */
.sp-hero-fullscreen {
    min-height: 100vh;
}
.sp-hero-large {
    min-height: 80vh;
}
.sp-hero-medium {
    min-height: 60vh;
}
.sp-hero-small {
    min-height: 45vh;
}

/* Video background — fills the hero, object-fit:cover crops as needed */
.sp-front-hero-video {
    position: absolute;
    top: 50%;
    left: 50%;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    transform: translate(-50%, -50%);
    object-fit: cover;
    z-index: 0;
}

/* Image background — same full-cover approach */
.sp-front-hero-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* WHY var(): the URL comes from settings, emitted as --sp-hero-bg on
     * the parent .sp-front-hero. Pulling it here keeps the inline style
     * out of the markup. */
    background-image: var(--sp-hero-bg, none);
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    z-index: 0;
}

/* Gradient fallback when no media is configured — dignified, not empty */
.sp-front-hero-gradient {
    background: linear-gradient(135deg,
        var(--sp-color-primary, #1e3a5f) 0%,
        color-mix(in srgb, var(--sp-color-primary, #1e3a5f), #000 30%) 50%,
        var(--sp-color-accent, #454FBF) 100%
    );
}

/* Dark overlay — opacity comes from --sp-hero-overlay-opacity on the
 * parent .sp-front-hero (set from the homepage_hero_overlay setting). */
.sp-front-hero-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #000;
    opacity: var(--sp-hero-overlay-opacity, 0.4);
    z-index: 1;
}

/* Content container — centered text above the overlay */
.sp-front-hero-content {
    position: relative;
    z-index: 2;
    text-align: center;
    padding: 40px 20px;
    max-width: 900px;
}

/* Eyebrow — small kicker line above the headline (e.g. "Welcome to the") */
.sp-front-hero-eyebrow {
    font-family: var(--sp-font-heading, 'Playfair Display', Georgia, serif);
    font-size: clamp(1.3rem, 3vw, 2rem);
    font-weight: 300;
    color: #fff;
    line-height: 1.2;
    margin: 0 0 4px 0;
    letter-spacing: 0.02em;
    text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
}

/* Headline — large, elegant serif (Playfair Display by default) */
.sp-front-hero-headline {
    font-family: var(--sp-font-heading, 'Playfair Display', Georgia, serif);
    font-size: clamp(2.2rem, 5vw, 4rem);
    font-weight: 400;
    color: #fff;
    line-height: 1.15;
    margin: 0 0 16px 0;
    letter-spacing: 0.02em;
    /* WHY text-shadow: Ensures readability even if the overlay is light
       or the background image has bright spots */
    text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
}

/* Subtitle — lighter weight, slightly smaller */
.sp-front-hero-subtitle {
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, sans-serif);
    font-size: clamp(1rem, 2vw, 1.35rem);
    font-weight: 300;
    color: rgba(255, 255, 255, 0.9);
    line-height: 1.6;
    margin: 0 0 32px 0;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
    text-shadow: 0 1px 10px rgba(0, 0, 0, 0.2);
}

/* CTA button — clean, outlined, stands out without being garish */
.sp-front-hero-cta {
    display: inline-block;
    padding: 14px 36px;
    font-family: var(--sp-font-body, -apple-system, BlinkMacSystemFont, sans-serif);
    font-size: 0.95rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #fff;
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.7);
    text-decoration: none;
    transition: all 0.3s ease;
}

.sp-front-hero-cta:hover {
    background: #fff;
    color: var(--sp-color-primary, #1e3a5f);
    border-color: #fff;
    text-decoration: none;
}

/* Scroll indicator — gentle bouncing chevron at the bottom */
.sp-front-hero-scroll {
    position: absolute;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    color: rgba(255, 255, 255, 0.6);
    animation: sp-hero-bounce 2s ease-in-out infinite;
}

@keyframes sp-hero-bounce {
    0%, 20%, 50%, 80%, 100% {
        transform: translateX(-50%) translateY(0);
    }
    40% {
        transform: translateX(-50%) translateY(-8px);
    }
    60% {
        transform: translateX(-50%) translateY(-4px);
    }
}

/* When hero is present, the content below doesn't need extra top padding */
.sp-front-has-hero {
    padding-top: 0;
}

/* Responsive: reduce hero headline size on small screens */
@media screen and (max-width: 768px) {
    .sp-front-hero-content {
        padding: 30px 16px;
    }
    .sp-front-hero-cta {
        padding: 12px 28px;
        font-size: 0.85rem;
    }
}

/* ============================================================================
   404 PAGE
   ============================================================================ */

.error-404 {
    text-align: center;
    padding: 60px 20px;
}

.error-404 h1 {
    font-size: calc(2.5rem * var(--sp-font-scale, 1));
    margin-bottom: 16px;
}

.error-404 p {
    font-size: 1.1rem;
    color: #6b7280;
    margin-bottom: 24px;
}

.error-404 .search-form {
    max-width: 400px;
    margin: 0 auto;
}

/* ============================================================================
   FORMS (search, comments, etc.)
   WHY: Large inputs with clear borders are easier to see and tap.
   ============================================================================ */

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
textarea {
    padding: 12px 14px;
    font-size: 1rem;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    font-family: inherit;
    width: 100%;
    max-width: 100%;
    transition: border-color 0.2s ease;
}

input:focus,
textarea:focus {
    outline: 2px solid var(--sp-color-accent, #454FBF);
    outline-offset: 2px;
    border-color: var(--sp-color-accent, #454FBF);
}

button,
input[type="submit"] {
    padding: 12px 24px;
    font-size: 1rem;
    font-weight: 600;
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.2s ease;
}

button:hover,
input[type="submit"]:hover {
    background: var(--sp-color-primary-hover, #2c5282);
}

button:focus-visible,
input[type="submit"]:focus-visible {
    outline: 2px solid var(--sp-color-accent, #c9973a);
    outline-offset: 2px;
}

/* ============================================================================
   WORDPRESS UTILITIES
   WHY: WordPress adds these classes for alignment and captions.
   We need to style them so content editors work as expected.
   ============================================================================ */

.alignleft {
    float: left;
    margin: 0 20px 20px 0;
}

.alignright {
    float: right;
    margin: 0 0 20px 20px;
}

.aligncenter {
    display: block;
    margin: 20px auto;
}

.wp-caption {
    max-width: 100%;
}

.wp-caption-text {
    font-size: 0.85rem;
    color: #6b7280;
    margin-top: 6px;
}

.screen-reader-text {
    border: 0;
    clip: rect(1px, 1px, 1px, 1px);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    word-wrap: normal !important;
}


/* ============================================================================
   MY ACCOUNT PAGE
   WHY: Frontend profile page so members can manage their account without
   ever seeing the WordPress backend. Three sections: photo, personal info,
   and password — each in a clearly separated card.
   ============================================================================ */

/* Each section (Photo, Info, Password) gets its own card */
/* WHY cap at 860px: Form inputs scale with the flex row they live in. When
   the page wrapper is 1100px+ and the section card fills it, "First Name"
   becomes as wide as "Street Address" and the eye loses the affordance that
   input width signals expected answer length. 860px keeps three-across rows
   at a comfortable form-scanning size on desktops. */
.sp-account-section {
    max-width: 860px;
    margin-left: auto;
    margin-right: auto;
    background: #f8f9fa;
    border-radius: 8px;
    padding: 30px;
    margin-bottom: 24px;
}

.sp-account-section h2 {
    font-size: calc(1.3rem * var(--sp-font-scale, 1));
    margin-bottom: 20px;
    padding-bottom: 12px;
    border-bottom: 2px solid var(--sp-color-primary, #1e3a5f);
}

/* ------- Success / Error Messages ------- */

.sp-notice {
    padding: 14px 20px;
    border-radius: 6px;
    margin-bottom: 24px;
    font-weight: 500;
    font-size: 0.95rem;
}

.sp-notice--success {
    background: #ecfdf5;
    color: #065f46;
    border: 1px solid #a7f3d0;
}

.sp-notice--error {
    background: #fef2f2;
    color: #991b1b;
    border: 1px solid #fecaca;
}

.sp-notice--pending {
    background: #fff8e1;
    border-left: 4px solid #f9a825;
    color: #5d4037;
}

.sp-notice--info {
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    color: #1e3a5f;
}

/* Read-only field summary shown when a My Account section is locked by the
   society (members can see their info but not edit it). */
.sp-account-readonly {
    margin: 0 0 8px;
}
.sp-account-readonly dt {
    font-weight: 600;
    margin-top: 10px;
}
.sp-account-readonly dd {
    margin: 2px 0 0;
}

/* ------- My Account renewal banner ------- */
/* WHY: A member who is expiring or expired sees the nav "Renew Now" CTA on
   every page, but the account page itself is where they manage membership,
   so it earns a louder, escalating banner. Amber for expiring, red for
   expired. A flex row keeps the message and the action button on one line
   on desktop and stacks them on narrow screens. */
.sp-renewal-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 16px 20px;
    border-radius: 6px;
    margin-bottom: 24px;
}
.sp-renewal-banner--expiring {
    background: #fff8e1;
    border: 1px solid #f9a825;
    border-left-width: 4px;
    color: #5d4037;
}
.sp-renewal-banner--expired {
    background: #fef2f2;
    border: 1px solid #ef4444;
    border-left-width: 4px;
    color: #991b1b;
}
.sp-renewal-banner__text { display: flex; flex-direction: column; gap: 2px; }
.sp-renewal-banner__title { font-size: 1.05rem; }
.sp-renewal-banner__detail { font-weight: 400; font-size: 0.95rem; }
/* Reuses the theme's .sp-button; this modifier just stops the button from
   shrinking when the message text is long. */
.sp-renewal-banner__btn { flex-shrink: 0; align-self: center; }

/* ------- Members Only Gate ------- */
/* WHY: Previously inline styles. Now classes so child themes can
   override the gate appearance via CSS custom properties. */

.sp-members-only-gate {
    text-align: center;
    padding: 60px 20px;
    max-width: 500px;
    margin: 0 auto;
}

.sp-members-only-icon {
    color: #767676;
    margin-bottom: 16px;
}

.sp-members-only-heading {
    margin: 0 0 12px;
    font-size: 1.4em;
}

.sp-members-only-text {
    color: var(--sp-color-text-secondary, #666);
    margin: 0 0 24px;
}

.sp-members-only-btn {
    display: inline-block;
    padding: 10px 28px;
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    text-decoration: none;
    border-radius: 4px;
    font-weight: 600;
}

.sp-members-only-btn:hover {
    opacity: 0.9;
    color: #fff;
}

/* ------- Photo Section ------- */

.sp-photo-section {
    display: flex;
    align-items: center;
    gap: 30px;
}

.sp-photo-preview {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid #dee2e6;
}

.sp-photo-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Hide the native file input — we use a styled label instead */
.sp-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
}

.sp-photo-hint {
    font-size: 0.8rem;
    color: #6b7280;
    margin: 0;
}

/* ------- Form Layout ------- */

.sp-account-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.sp-form-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.sp-form-field label {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--sp-color-primary, #1e3a5f);
}

/* A .sp-form-field that is a <fieldset> (e.g. the Preferred Phone radio group):
   strip the browser's default fieldset chrome and style its <legend> to match
   the plain field labels above, so the semantic grouping is invisible visually
   but announced to screen readers. */
.sp-form-fieldset {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}
.sp-form-fieldset > legend {
    padding: 0;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--sp-color-primary, #1e3a5f);
}

/* Month and day pickers for a birthday given without a year. */
.sp-birthday-noyear {
    display: flex;
    gap: 8px;
}
.sp-birthday-noyear select {
    flex: 1;
}

/* Free-text research note on a surname / research-area / relationship row.
   Smaller and muted so it reads as a note, not another surname. */
.sp-surname-note {
    font-size: 0.85em;
    font-style: italic;
    color: var(--sp-color-text-secondary, #6b7280);
}

/* Inline radio group inside a .sp-form-field — used for preferred-phone
   choices and other "pick one" rows. */
.sp-radio-row {
    display: flex;
    gap: 20px;
    margin-top: 4px;
}

.sp-radio-row__option {
    font-weight: 400;
}

/* Visually-uppercase input — used for surname inputs so members see all-caps
   while typing. */
.sp-input--uppercase {
    text-transform: uppercase;
}

/* Hint shown under a surname row when other members are also researching
   the same name. Color matches the rest of the WP-blue link/info accents. */
.sp-surname-similar {
    display: block;
    font-size: 12px;
    color: #2271b1;
    margin-top: 2px;
}

.sp-field-hint {
    font-size: 0.8rem;
    color: #6b7280;
    margin: 0;
}

/* Side-by-side fields (first name / last name, etc.) */
.sp-form-row--half {
    display: flex;
    gap: 16px;
}

.sp-form-row--half .sp-form-field {
    flex: 1;
}

/* Three-column fields (prefix / first / middle / last) */
.sp-form-row--thirds {
    display: flex;
    gap: 16px;
}

.sp-form-row--thirds .sp-form-field {
    flex: 1;
}

/* City / State / Zip row — city gets more space */
.sp-form-row--city-state {
    display: flex;
    gap: 16px;
}

.sp-form-field--city {
    flex: 2;
}

.sp-form-field--state {
    flex: 1;
}

.sp-form-field--zip {
    flex: 1;
}

/* Select dropdowns — match text input styling */
select {
    padding: 12px 14px;
    font-size: 1rem;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    font-family: inherit;
    width: 100%;
    max-width: 100%;
    background: #fff;
    transition: border-color 0.2s ease;
    appearance: auto;
}

select:focus {
    outline: 2px solid var(--sp-color-accent, #454FBF);
    outline-offset: 2px;
    border-color: var(--sp-color-accent, #454FBF);
}

/* Date inputs — match text input styling */
input[type="date"] {
    padding: 12px 14px;
    font-size: 1rem;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    font-family: inherit;
    width: 100%;
    transition: border-color 0.2s ease;
}

input[type="date"]:focus {
    outline: 2px solid var(--sp-color-accent, #454FBF);
    outline-offset: 2px;
    border-color: var(--sp-color-accent, #454FBF);
}

/* Checkbox group — vertical stack with comfortable spacing */
.sp-checkbox-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
}

/* Individual checkbox label — large click target for older users */
.sp-checkbox-label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.95rem;
    cursor: pointer;
    padding: 4px 0;
}

.sp-checkbox-label input[type="checkbox"] {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    cursor: pointer;
    accent-color: var(--sp-color-primary, #1e3a5f);
}

/* Checkboxes governed by a master switch above them. Indented and ruled so
   the dependency is visible before it's tested, greyed while the switch is on.
   Colors stay above the 4.5:1 contrast floor even in the disabled state —
   these still have to be readable by the members most likely to tick it. */
.sp-checkbox-group--dependent {
    border-left: 3px solid var(--sp-color-border, #e5e7eb);
    padding-left: 16px;
    margin-left: 6px;
}

.sp-checkbox-group--dependent.is-disabled .sp-checkbox-label {
    color: #767676;
    cursor: default;
}

.sp-checkbox-group--dependent.is-disabled .sp-checkbox-label input[type="checkbox"] {
    cursor: default;
}

/* Seasonal address subsection heading */
.sp-subsection-heading {
    font-size: calc(1.1rem * var(--sp-font-scale, 1));
    margin-top: 16px;
    margin-bottom: 16px;
    padding-top: 12px;
    border-top: 1px solid #dee2e6;
}

/* Seasonal toggle checkbox (inside the address form) */
.sp-seasonal-toggle {
    margin-top: 8px;
}

/* Section description text (used in Directory Privacy) */
.sp-section-description {
    font-size: 0.9rem;
    color: #6b7280;
    margin-bottom: 16px;
    margin-top: -8px;
}

/* ------- Buttons ------- */

.sp-button {
    display: inline-block;
    padding: 10px 20px;
    font-size: 0.9rem;
    font-weight: 600;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
    transition: background 0.2s ease;
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    width: auto;
    align-self: flex-start;
}

.sp-button:hover {
    background: var(--sp-color-primary-hover, #2c5282);
    color: #fff;
}

.sp-button:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--sp-color-primary, #1e3a5f);
}

.sp-button--secondary {
    background: #fff;
    color: var(--sp-color-primary, #1e3a5f);
    border: 2px solid var(--sp-color-primary, #1e3a5f);
}

.sp-button--secondary:hover {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
}

/* Text-style button for "Remove Photo" — subtle, not prominent */
.sp-button--text {
    background: none;
    border: none;
    color: #991b1b;
    font-size: 0.85rem;
    font-weight: 500;
    padding: 4px 0;
    cursor: pointer;
    text-decoration: underline;
}

.sp-button--text:hover {
    color: #7f1d1d;
    background: none;
}

/* ============================================================================
   RESPONSIVE
   WHY: Single column on mobile. The sidebar moves below content so the
   main content is always visible first.
   ============================================================================ */

/* ============================================================================
   NAV COLLAPSE — 1280px
   WHY 1280px instead of 768px: With 7 nav items plus social icons, search,
   and user menu, the horizontal nav wraps awkwardly between 768–1280px.
   Collapsing at 1280px (the media query below) prevents the nav from ever
   wrapping to two lines on smaller laptops and tablets.
   ============================================================================ */

@media (max-width: 1280px) {

    /* === HAMBURGER + MOBILE NAV COLLAPSE ===
       WHY: The full horizontal nav wraps or overflows on narrow screens.
       We hide the nav behind a hamburger toggle that reveals a full-width
       dropdown panel below the header. The search toggle and user menu
       remain visible outside the hamburger panel — they're separate elements
       in .header-nav-area and don't get hidden. */

    .header-inner {
        /* WHY relative: The mobile nav panel is absolutely positioned relative
           to the header-inner so it drops below it cleanly. */
        position: relative;
        padding: 16px 0;
    }

    /* Show the hamburger button — on the right side */
    .sp-hamburger {
        display: block;
        order: 99;
    }

    /* Nav area stays horizontal on mobile — hamburger, search toggle, and
       user menu sit in a row. The nav itself drops below as a panel. */
    .header-nav-area {
        width: 100%;
        /* WHY static: The mobile nav panel positions itself relative to
           header-inner, not header-nav-area. Static lets the panel break
           out of this flex container. */
        position: static;
    }

    /* Hide the PRIMARY nav on mobile — revealed when sp-nav-open is added.
       The :not(.sp-user-menu) exclusion keeps the Sign In / user dropdown
       visible in the header row alongside the hamburger. */
    .main-navigation:not(.sp-user-menu) {
        display: none !important;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--sp-color-nav-bg, var(--sp-color-header-bg, #1e3a5f));
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
        z-index: 999;
        border-top: 3px solid var(--sp-color-accent, rgba(255, 255, 255, 0.2));
    }

    /* Show the nav panel when JS adds sp-nav-open */
    .main-navigation.sp-nav-open {
        display: block !important;
    }

    /* Stack nav links vertically in the mobile panel */
    .main-navigation > ul {
        flex-direction: column;
        gap: 0;
    }

    /* WHY: On desktop, .sp-nav-right items use margin-left:auto to push
       Store/Contact/Join to the right edge. In the mobile panel the nav
       is stacked vertically, so that auto margin shoves the item to the
       far right instead of left-aligning with everything else. */
    .main-navigation > ul > li.sp-nav-right {
        margin-left: 0 !important;
    }

    .main-navigation > ul > li {
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .main-navigation > ul > li:last-child {
        border-bottom: none;
    }

    .main-navigation a {
        padding: 14px 20px;
        font-size: 1rem;
        border-radius: 0;
    }

    .main-navigation a:hover,
    .main-navigation .current-menu-item a {
        background: rgba(255, 255, 255, 0.1);
    }

    /* Sub-menus in mobile nav — static, stacked, indented instead of floating */
    .main-navigation .sub-menu {
        position: static;
        box-shadow: none;
        border-top: none;
        border-radius: 0;
        min-width: 0;
        padding: 0;
        background: rgba(0, 0, 0, 0.15);
    }

    /* One step of indent per level, so a visitor can see where they are in a
       menu that nests further than the eye can hold. The stacked translucent
       backgrounds already darken with depth; the indent is what tells level 5
       apart from level 2 rather than merely apart from the page.

       WHY a rule per level instead of a descendant selector: a chained
       .sub-menu .sub-menu applies to every level below the one it describes as
       well, so the indents would compound wrongly. The walker stamps each list
       with its own level, and eight of them is past any menu a society will
       build — beyond that the indent stops growing, which costs nothing but a
       little clarity, and the items still render. */
    .main-navigation .sp-submenu-level-1 > li > a { padding-left: 36px; }
    .main-navigation .sp-submenu-level-2 > li > a { padding-left: 52px; }
    .main-navigation .sp-submenu-level-3 > li > a { padding-left: 68px; }
    .main-navigation .sp-submenu-level-4 > li > a { padding-left: 84px; }
    .main-navigation .sp-submenu-level-5 > li > a { padding-left: 100px; }
    .main-navigation .sp-submenu-level-6 > li > a { padding-left: 116px; }
    .main-navigation .sp-submenu-level-7 > li > a { padding-left: 132px; }
    .main-navigation .sp-submenu-level-8 > li > a { padding-left: 148px; }

    /* Show sub-menus when parent is toggled open */
    .main-navigation > ul > li.menu-item-has-children:hover > .sub-menu {
        display: none;
    }
    .main-navigation > ul > li.menu-item-has-children.sp-submenu-open > .sub-menu {
        display: block;
    }

    /* ------------------------------------------------------------------
       DROP DOWN CARETS IN THE MOBILE PANEL
       A parent item is two things at once — a page of its own and the lid
       on the pages beneath it. In the stacked panel each gets its own
       target: the name goes to the page, the caret opens the drop down.
       ------------------------------------------------------------------ */

    /* WHY flex-wrap and not absolute positioning: the sub-menu is a sibling
       of the name inside the same <li>, so a caret positioned against that
       <li> would center itself over the whole expanded block once the drop
       down was showing. Wrapping puts the name and caret on one row and
       gives the sub-menu the full width of the next. */
    .main-navigation li.menu-item-has-children {
        display: flex;
        flex-wrap: wrap;
        align-items: stretch;
    }

    .main-navigation li.menu-item-has-children > a {
        flex: 1 1 auto;
        min-width: 0;
    }

    .main-navigation li.menu-item-has-children > .sub-menu {
        flex: 0 0 100%;
    }

    /* The small triangle drawn on the link is the desktop hover hint. The
       caret button says the same thing here, so showing both would put two
       arrows on one row. */
    .main-navigation li.menu-item-has-children > a::after {
        display: none;
    }

    .sp-submenu-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        /* 44px is the smallest target a fingertip hits reliably; 56px keeps
           it comfortably clear of the name beside it. */
        flex: 0 0 56px;
        min-height: 44px;
        padding: 0;
        background: none;
        border: none;
        border-left: 1px solid rgba(255, 255, 255, 0.1);
        color: var(--sp-color-header-text, #fff);
        cursor: pointer;
        opacity: 0.75;
    }

    .sp-submenu-toggle:hover {
        background: rgba(255, 255, 255, 0.1);
        opacity: 1;
    }

    .sp-submenu-toggle:focus-visible {
        outline: 2px solid var(--sp-color-accent, #fff);
        outline-offset: -2px;
    }

    .sp-submenu-toggle svg {
        transition: transform 0.2s ease;
    }

    .main-navigation li.menu-item-has-children.sp-submenu-open > .sp-submenu-toggle svg {
        transform: rotate(180deg);
    }

    .main-navigation li.menu-item-has-children.sp-submenu-open > .sp-submenu-toggle {
        opacity: 1;
    }

    .main-navigation .sub-menu a {
        padding: 12px 20px 12px 36px;
        font-size: 0.95rem;
    }

    .main-navigation .sub-menu li + li {
        border-top: 1px solid rgba(255, 255, 255, 0.06);
    }

    /* WHY: On mobile the site title can be long enough to push the hamburger
       off-screen (e.g. "Heritage Valley Historical Society" at 320px). We
       shrink the font, allow the branding block to shrink via min-width:0,
       and truncate with ellipsis so the hamburger always stays visible. */
    .site-branding {
        min-width: 0;
        flex-shrink: 1;
    }

    .site-title {
        font-size: 1rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .site-description {
        display: none;
    }

    /* On mobile, hide the name and just show the avatar to save space */
    .sp-user-name {
        display: none;
    }

    /* WHY hide the signed-in account slot once the menu carries the account
       links: at phone width it was a bare silhouette nobody read as Log Out.
       The first :has() keeps it for any menu without those links — no menu
       assigned yet, or a theme that puts its navigation elsewhere. */
    .header-nav-area:has(.main-navigation .sp-nav-account) .sp-user-menu:has(.sp-user-trigger) {
        display: none;
    }

    /* WHY "Log In" stays on show when signed out: a member arriving on a phone
       should not have to guess it is inside the menu. It goes on the far side
       of the menu button because wedged between the logo and the button it read
       as a stray word. The hamburger guard leaves alone any theme that has not
       collapsed its menu at this width, where the margin would overflow it. */
    .header-nav-area:has(> .sp-hamburger) .sp-user-menu:has(.sp-user-login-link) {
        order: 100;
        margin-left: auto;
    }

    .sp-user-trigger {
        padding: 6px 10px;
    }

    /* Center the dropdown on mobile instead of right-aligning */
    .sp-user-dropdown {
        right: auto;
        left: 50%;
        transform: translateX(-50%) translateY(-4px);
    }

    .sp-user-menu:hover .sp-user-dropdown,
    .sp-user-menu:focus-within .sp-user-dropdown,
    .sp-user-menu.sp-user-open .sp-user-dropdown {
        transform: translateX(-50%) translateY(0);
    }

} /* end 1280px nav collapse */


@media (max-width: 768px) {
    html {
        /* WHY we clamp mobile font size: On small screens, the chosen base
           size might be too large. We use a slightly smaller size but still
           respect the user's preference via the CSS variable. */
        font-size: 16px;
    }

    .content-area-with-sidebar {
        flex-direction: column;
    }

    .content-area-with-sidebar .widget-area {
        width: 100%;
    }

    .site-content {
        padding: 24px 16px;
    }

    /* My Account page: stack photo above actions, full-width name fields */
    .sp-photo-section {
        flex-direction: column;
        text-align: center;
    }

    .sp-photo-actions {
        align-items: center;
    }

    .sp-form-row--half,
    .sp-form-row--thirds,
    .sp-form-row--city-state {
        flex-direction: column;
    }

    .sp-account-section {
        padding: 20px;
    }
}


/* ============================================================================
   NEWSLETTER ARCHIVE — Frontend Grid, Cards, and PDF Viewer Modal

   WHY: The newsletter archive needs a visually appealing card grid to
        showcase PDF covers. Cards use a portrait aspect ratio (more natural
        for printed newsletter covers than the landscape ratio used for photo
        albums). The PDF viewer modal uses an iframe to leverage the browser's
        native PDF renderer — no third-party library needed.
   ============================================================================ */

/* Grid — 3 columns on desktop, 2 on tablet, 1 on mobile */
.sp-newsletter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 24px;
    margin-top: 8px;
}

/* Individual card */
.sp-newsletter-card {
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    overflow: hidden;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.sp-newsletter-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    transform: translateY(-2px);
}

/* Cover image area — portrait aspect ratio for newsletter covers */
.sp-newsletter-card-cover {
    position: relative;
    width: 100%;
    aspect-ratio: 8.5 / 11; /* US Letter proportions */
    overflow: hidden;
    background: #f0f0f0;
}

.sp-newsletter-card-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Placeholder when no cover image exists */
.sp-newsletter-card-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Card body — title, date, description, actions */
.sp-newsletter-card-body {
    padding: 14px;
}

.sp-newsletter-card-title {
    margin: 0 0 4px;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--sp-color-primary, #1e3a5f);
}

.sp-newsletter-card-date,
.sp-newsletter-card-issue {
    display: block;
    font-size: 0.85rem;
    color: #595959;
    line-height: 1.4;
}

.sp-newsletter-card-desc {
    font-size: 0.85rem;
    color: #555;
    margin: 6px 0 0;
    line-height: 1.4;
    /* Clamp to 2 lines to keep cards uniform height */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.sp-newsletter-card-actions {
    margin-top: 10px;
}

/* Buttons.
   WHY the second selector: the PDF reader is no longer newsletter-only — the
   store opens samples in it too. Anything outside the newsletter archive uses
   the neutral name so no module has to wear another module's class. */
.sp-newsletter-btn,
.sp-pdf-modal-btn {
    display: inline-block;
    padding: 6px 14px;
    font-size: 0.85rem;
    font-weight: 500;
    border-radius: 6px;
    text-decoration: none;
    cursor: pointer;
    border: none;
    line-height: 1.4;
    transition: background 0.2s ease;
}

/* "Read Online" is the primary action, so it carries the solid fill. Download
   is the secondary path and is outlined, which is what tells someone at a
   glance that reading is the ordinary way in and downloading is optional. */
.sp-newsletter-btn-read {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    margin-right: 6px;
}

.sp-newsletter-btn-read:hover {
    background: var(--sp-color-primary-hover, #2c5282);
    color: #fff;
}

.sp-newsletter-btn-download {
    background: transparent;
    color: var(--sp-color-primary, #1e3a5f);
    box-shadow: inset 0 0 0 1px currentColor;
}

.sp-newsletter-btn-download:hover {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
}

/* Inside the reader the download link is the only action, so it keeps the
   solid treatment rather than sitting there looking disabled. */
.sp-pdf-modal .sp-newsletter-btn-download,
.sp-pdf-modal .sp-pdf-modal-btn-download {
    background: var(--sp-color-primary, #1e3a5f);
    color: #fff;
    box-shadow: none;
}

.sp-pdf-modal .sp-newsletter-btn-download:hover,
.sp-pdf-modal .sp-pdf-modal-btn-download:hover {
    background: var(--sp-color-primary-hover, #2c5282);
    color: #fff;
}

/* Members-only badge shown to non-logged-in users */
.sp-newsletter-members-badge {
    display: inline-block;
    padding: 4px 10px;
    font-size: 0.8rem;
    font-weight: 500;
    background: #fef0c7;
    color: #92400e;
    border-radius: 4px;
}


/* ========== PDF VIEWER MODAL ========== */

/* Full-screen overlay + centered content container */
.sp-pdf-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Dark semi-transparent backdrop */
.sp-pdf-modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.7);
}

/* Modal content box — takes up most of the viewport */
.sp-pdf-modal-content {
    position: relative;
    width: 90vw;
    height: 90vh;
    max-width: 1200px;
    background: #fff;
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Header bar with title + actions */
.sp-pdf-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 20px;
    background: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
    flex-shrink: 0;
}

.sp-pdf-modal-header h3 {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    padding-right: 16px;
}

.sp-pdf-modal-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Close button */
.sp-newsletter-btn-close,
.sp-pdf-modal-btn-close {
    background: #e5e7eb;
    color: #374151;
    font-size: 1.3rem;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 6px;
}

.sp-newsletter-btn-close:hover,
.sp-pdf-modal-btn-close:hover {
    background: #d1d5db;
}

/* iframe fills the remaining space */
.sp-pdf-modal-body {
    flex: 1;
    overflow: hidden;
}

.sp-pdf-modal-body iframe {
    width: 100%;
    height: 100%;
    border: none;
}


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

@media (max-width: 768px) {
    .sp-newsletter-grid {
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
        gap: 16px;
    }

    .sp-pdf-modal-content {
        width: 100vw;
        height: 100vh;
        border-radius: 0;
    }

    .sp-pdf-modal-header h3 {
        font-size: 0.95rem;
    }
}

@media (max-width: 480px) {
    .sp-newsletter-grid {
        grid-template-columns: 1fr;
    }
}
