html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
  position: relative;
  min-height: 100%;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}
/* ---------- Globe51: single-page site ---------- */

:root {
  --g26-navy: #004278;
  --g26-navy-soft: rgba(0, 66, 120, 0.08);
  --g26-blue: #006ac1;
  --g26-blue-soft: rgba(0, 106, 193, 0.10);
  --g26-accent: #6db0e3;
  --g26-text: #26313d;
  --g26-muted: #6c7680;
  --g26-card-shadow: 0 10px 30px rgba(0, 30, 58, 0.25);
  /* Space Grotesk (geometric, a little technical) paired with Inter
     (the body face already in use) -- a common pairing for tech/corporate
     sites, replacing the more editorial serif this used before. */
  --font-display: "Space Grotesk", "Segoe UI", Arial, sans-serif;
  --font-body: "Inter", Calibri, Arial, sans-serif;
  /* Solid, not a gradient -- a bold flat corporate-blue field reads more
     deliberate/confident behind the white content cards than a soft
     near-white gradient did. */
  --g26-page-bg: #004278;
}

html, body {
  /* min-height, not height -- a fixed height clips the body (and the
     solid color painted on it) to exactly one viewport, so a tall page
     (e.g. once the contact form pushed the Contact panel past that)
     overflows past the color fill instead of it growing to cover it.
     100vh, not 100% -- body's min-height only resolves as a percentage
     against html's own *computed* height, but html only ever declares
     min-height itself (never a definite height), so that chain doesn't
     reliably resolve and the color was only filling as far as the
     content instead of the full viewport. vh measures against the
     viewport directly, sidestepping that -- already the idiom used
     elsewhere in this file (.hero-wrap, .demo-mode-notice). */
  min-height: 100vh;
  margin: 0;
  /* .content-panel's slide-in-from-the-left entrance (below) starts
     from off the left edge of the window, which would otherwise leave
     the page briefly horizontally scrollable for the ~0.4s the
     animation takes. */
  overflow-x: hidden;
}

/* The page's background color lives on html ONLY, not body. html and body
   each compute their own box height independently, and on a page tall
   enough to actually scroll (only the Contact tab, with its longer form,
   among these panels) their two fractional heights can round to the
   pixel grid a hair apart -- when BOTH elements painted this color
   separately (as this used to), that sub-pixel mismatch left a real,
   visible 1px gap of unpainted canvas at their seam, confirmed directly
   from a screenshot (a hairline between two otherwise-identical blue
   bands). Since body has no background of its own, it's transparent, and
   html's background shows straight through it for the whole visible
   page -- there's only ever one box painting this color, so there's no
   second, independently-rounded box left to create a seam against. html's
   background is also what the browser uses to paint the overscroll/
   rubber-band area beyond the page, so this one rule still covers both
   cases the two-element version was trying to.
   White for the home/hero (slideshow) state -- the default, since that's
   what a fresh page load always shows. Swaps to the solid corporate-blue
   field once a content panel is open, via html.has-active below (toggled
   by site.js when a nav link is picked), timed to match the hero's own
   0.5s collapse transition. */
html {
  background-color: #ffffff;
  transition: background-color 0.5s ease;
}

html.has-active {
  background-color: var(--g26-page-bg);
}

body {
  font-family: var(--font-body);
  color: var(--g26-text);
}

/* A small real, solid-colored band right at the end of the page. The
   page's true height is a fractional number of CSS pixels, and Chrome
   can expose that leftover sliver as a hairline gap of its default
   canvas color (white) right at the bottom edge during an elastic
   overscroll/rubber-band bounce -- only reachable at all once the page
   is actually tall enough to scroll (in practice, only the Contact
   panel, with its longer form). Rather than chasing that fraction of a
   pixel to try to make it exactly zero (tried, and the browser's own
   layout rounding won't land it any closer than about 1/64px -- still
   occasionally visible), this element gives that sliver somewhere to
   land that's already the right color: 3px is comfortably larger than
   any such rounding error, so wherever the true content edge actually
   falls within that band, both sides of it are the same solid color
   and there's nothing left to see a seam between. */
#g26ScrollSpacer {
  display: block;
  height: 3px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: #ffffff;
  transition: background-color 0.5s ease;
}

html.has-active #g26ScrollSpacer {
  background-color: var(--g26-page-bg);
}

/* Shown at the very top of the page whenever the visitor is logged in (see
   Index.cshtml) -- a quick way back into /Admin without having to remember
   or type the URL. The toggle button collapses it down to a slim strip
   (rather than hiding it entirely) so it's still there to bring back, but
   stops taking up space once someone's seen it. Once collapsed, hovering
   the strip for a moment (site.js) reveals it again the way a browser's
   own auto-hiding bars do, via the .peeking class below -- clicking the
   toggle is still there as the deliberate, permanent way to expand it
   again (or to collapse it back down), but isn't the only way in. */
.admin-banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem 2.75rem;
  background: linear-gradient(135deg, var(--g26-navy), var(--g26-blue));
  text-align: center;
  transition: padding 0.2s ease;
}

.admin-banner.collapsed {
  padding: 0.3rem 2.75rem;
  /* Signals the strip is hoverable (it reveals itself on hover) right
     away, rather than only once the reveal itself has already happened. */
  cursor: pointer;
}

/* Collapsed down to its slim strip, neither the text nor the toggle
   button are shown -- there's nothing left to clip or poke out, so the
   strip can actually be slim. Both reappear together once .peeking
   (site.js, on hover) or a real expand brings back the full padding. */
.admin-banner.collapsed:not(.peeking) .admin-banner-text,
.admin-banner.collapsed:not(.peeking) .admin-banner-toggle {
  display: none;
}

.admin-banner.collapsed.peeking {
  padding: 0.6rem 2.75rem;
}

.admin-banner-text {
  color: #ffffff;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

.admin-banner-text:hover {
  text-decoration: underline;
}

.admin-banner-toggle {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: rgba(255, 255, 255, 0.15);
  border: none;
  border-radius: 50%;
  color: #ffffff;
  font-size: 0.65rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}

.admin-banner-toggle:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* The pin emoji (shown only while collapsed -- see site.js) renders much
   smaller than the plain arrow glyph at the same font-size, so it needs
   its own larger size to actually fill the button. */
.admin-banner.collapsed .admin-banner-toggle {
  font-size: 1rem;
}

/* Shown instead of the whole page when SiteConfig.IsDemoMode is on and no
   one's logged in (see Index.cshtml) -- centers a single card in the
   viewport rather than trying to fit the site's usual header/hero/nav
   layout around one message. The page background now defaults to white
   (it's only blue while a content panel is open, see html.has-active
   above) -- this replaces the whole page rather than sitting alongside
   the hero, so it keeps its own explicit blue field regardless of that. */
.demo-mode-notice {
  min-height: 100vh;
  background-color: var(--g26-page-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  box-sizing: border-box;
  text-align: center;
}

.demo-mode-notice p {
  max-width: 480px;
  margin: 0;
  padding: 2rem 2.25rem;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: var(--g26-card-shadow);
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--g26-text);
}

.demo-mode-notice strong {
  color: var(--g26-navy);
}

.demo-mode-notice a {
  color: var(--g26-blue);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 106, 193, 0.35);
}

.demo-mode-notice a:hover {
  border-bottom-color: var(--g26-blue);
}

/* .hero-wrap's height and .hero's transform both animate over 0.5s (below)
   when a nav item is chosen or the logo is clicked. The content panel
   shows/hides the instant that happens, though, not after the hero
   finishes collapsing/expanding -- so for that half-second the page is
   briefly taller (collapsing) or shorter (expanding) than it settles at,
   which flashes a scrollbar on and straight back off. site.js adds this
   class for exactly that half-second to suppress the flash without
   otherwise changing how the page scrolls. */
body.hero-transitioning {
  overflow: hidden;
}

/* ----- shared icon-in-circle motif, used in the nav and again as a
   small marker on each content panel's heading ----- */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  /* Frosted-glass circle -- the soft navy/blue tint this used before was
     designed to show up against a near-white page; against the solid
     navy page background it sits on now, a translucent white reads the
     same way that tint used to. */
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.06));
  transition: background 0.2s ease, transform 0.2s ease;
}

.icon-badge--panel {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
}

.icon-badge--panel img {
  width: 24px;
  height: 24px;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.25rem 2rem;
  /* White titlebar, matching the admin topbar -- the logo's own dark
     gradient stop matches the new solid navy page background almost
     exactly, so without a light surface under it the mark loses its
     own edge and reads as a half-formed smudge instead of a globe. */
  background: #ffffff;
  box-shadow: 0 2px 10px rgba(0, 66, 120, 0.08);
  position: relative;
  z-index: 2;
}

.site-header-brand {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  cursor: pointer;
}

.site-logo {
  height: 64px;
  width: auto;
}

.site-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2.1rem;
  margin: 0;
  color: var(--g26-navy);
  letter-spacing: 0.01em;
}

/* ----- top-right text nav, collapsing to a hamburger menu ----- */

.nav-toggle {
  display: none;
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.nav-scrim {
  display: none;
}

/* Hero: sits below the header on the home state, sized to whatever room
   is left in the browser window so the page mostly fits one screen. When
   a nav item is chosen it slides up and collapses out of the document
   flow -- .hero-tagline and .site-content below it rise to take its
   place. */
.hero-wrap {
  margin-top: 1em;
  padding: 0 2rem;
  overflow: hidden;
  height: clamp(160px, calc(100vh - 240px), 560px);
  transition: height 0.5s ease;
  box-sizing: border-box;
}

.hero-wrap.collapsed {
  height: 0;
}

.hero {
  position: relative;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: var(--g26-card-shadow);
  transition: transform 0.5s ease;
}

.hero-wrap.collapsed .hero {
  transform: translateY(-100%);
}

.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.hero-slide.active {
  opacity: 1;
  z-index: 1;
}

/* Checkerboard reveal: rather than a plain crossfade (or a CSS mask
   that would show both pictures at once through a static checker
   grid), the outgoing picture is snapshotted onto this canvas -- laid
   directly over the slides -- the instant the incoming one is switched
   in underneath it. From there site.js (see runCheckerReveal) wipes
   the snapshot away in ~10x10px squares, each fading out on its own
   in a smooth diagonal sweep a few squares at a time, revealing the
   real incoming picture beneath as it goes. At rest the canvas is
   simply empty/transparent, so there's nothing to see and nothing
   sitting over the picture between transitions. */
.hero-checker-canvas {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

/* <picture> is inline by default, which -- like the <img> it wraps --
   leaves a few stray pixels of baseline gap beneath it if not overridden. */
.hero-slide picture {
  display: block;
  width: 100%;
  height: 100%;
}

.hero-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(15, 32, 51, 0.85) 0%, rgba(15, 32, 51, 0.35) 35%, rgba(15, 32, 51, 0) 65%);
}

.hero-caption {
  position: absolute;
  right: 1.75rem;
  bottom: 1.5rem;
  max-width: 70%;
  color: #ffffff;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 2.4vw, 1.6rem);
  letter-spacing: 0.01em;
  text-align: right;
  /* A crisp bottom-right drop shadow for definition against busy/light
     photo backgrounds, plus the original soft ambient glow underneath it
     for general legibility on any image. */
  text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.85), 0 2px 10px rgba(0, 0, 0, 0.35);
  /* Default/reset state: hidden and empty, ready for the next slide's
     typewriter entrance (site.js reveals its text one character at a
     time into .hero-caption-text, rather than this being a CSS
     transition of its own). The caption itself never moves or fades as
     a block on the way out either -- site.js instead has its individual
     letters fall away out of view in turn (see .hero-caption-letter
     below) and only ever resets back to this plain state once every
     letter's gone, at which point there's nothing left to see -- so
     this rule's own transition is just a non-janky fallback, not
     something normally seen in use. */
  opacity: 0;
  transition: opacity 0.3s ease;
}

/* Once .hero-slide's own 2s crossfade (below) has finished, site.js
   starts typing the caption's text out one character at a time (see
   typeCaption there) and adds this class, which just makes the caption
   itself visible -- the actual "typing" is the text span filling in,
   not anything animated here. Driven by a class of its own, rather than
   keyed off .hero-slide.active directly, so the very first slide on
   page load can start with its caption genuinely hidden and play this
   same entrance once, instead of just appearing already in place. */
.hero-caption.is-visible {
  opacity: 1;
}

/* Once a caption's pause is over, site.js rebuilds its already-typed
   text into one of these per letter (see startWaterfallExit there) and
   staggers adding .is-falling to each in turn, left to right, so they
   drop away out of view one at a time -- a waterfall -- while the rest
   of the not-yet-fallen text stays exactly where it was typed. Real
   elements rather than a single block-level exit transition because
   each letter needs to animate independently of its neighbors.
   inline-block (rather than the plain inline a span is by default) is
   what makes transform apply per letter at all. */
.hero-caption-letter {
  display: inline-block;
  transition: transform 0.4s ease, opacity 0.4s ease;
}

.hero-caption-letter.is-falling {
  transform: translateY(1em);
  opacity: 0;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.nav-item {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.5rem 0.25rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1rem;
  color: var(--g26-navy);
  position: relative;
  transition: color 0.15s ease;
}

.nav-item:hover {
  color: var(--g26-blue);
}

.nav-item.active {
  color: var(--g26-blue);
}

/* Underline indicator for the active link, rather than the old
   icon-badge highlight -- there's no icon left to carry that state. */
.nav-item.active::after {
  content: "";
  position: absolute;
  left: 0.25rem;
  right: 0.25rem;
  bottom: -0.3rem;
  height: 2px;
  border-radius: 1px;
  background: var(--g26-blue);
}

/* Sits where the old icon nav bar used to be, directly under the hero --
   homepage tagline copy rather than navigation, so (unlike the nav, which
   moved into the header and stays visible everywhere) it collapses away
   together with the hero once a panel is picked, via the same
   .hero-wrap.collapsed state site.js already toggles (a sibling
   selector, so no JS changes needed here). */
.hero-tagline {
  text-align: center;
  padding: 1.5rem 2rem 0.5rem;
  max-height: 200px;
  opacity: 1;
  overflow: hidden;
  transition: max-height 0.5s ease, opacity 0.3s ease, padding 0.5s ease;
}

.hero-wrap.collapsed ~ .hero-tagline {
  max-height: 0;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
}

.hero-tagline-heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.9rem;
  color: var(--g26-navy);
  margin: 0 0 0.4rem;
  letter-spacing: 0.01em;
}

.hero-tagline-subheading {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--g26-blue);
  margin: 0;
}

.site-content {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 2rem;
}

/* No content panel is shown until a nav item is picked (the home/hero
   state) -- .content-panel below is display:none for all of them at that
   point, but this element's own top/bottom padding still took up space
   regardless, which was enough on its own to push the page past one
   viewport and show a scrollbar even though nothing was actually visible
   down there. Restore the padding only once a panel is showing. The nav
   now lives inside the header rather than as .site-content's own
   sibling, so this is keyed off a class on <body> (site.js) instead of
   off .site-nav itself. */
body.has-active .site-content {
  padding: 1.75rem 2rem 3rem;
}

.content-panel {
  display: none;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: var(--g26-card-shadow);
  padding: 2rem 2.25rem 2.25rem;
}

.content-panel.active {
  display: block;
  animation: g26-fade-in 0.3s ease;
}

@keyframes g26-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Switching directly between two panels (see showPanel in site.js)
   gets a different transition than going to/from the hero, which
   keeps the plain fade above exactly as it always was: the outgoing
   card flies straight up and off the top of the window first, and
   only once it's fully gone does the incoming one appear and slide in
   from the left. site.js adds is-leaving, waits out the same duration
   as its animation below, and only then actually swaps which panel is
   .active -- .active's own display:block stays in effect on the
   outgoing card the whole time this plays, so it doesn't just wink out
   before it's flown clear. is-swapping-in (a higher-specificity
   override of .active's own plain fade-in above) is what marks the
   incoming card as part of this same panel-to-panel swap rather than
   a hero<->panel one. */
.content-panel.is-leaving {
  animation: g26-panel-fly-out-top 0.45s ease-in forwards;
}

.content-panel.active.is-swapping-in {
  animation: g26-panel-slide-in 0.4s ease-out;
}

@keyframes g26-panel-fly-out-top {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(-120vh); opacity: 0; }
}

@keyframes g26-panel-slide-in {
  from { transform: translateX(-110vw); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

.panel-heading {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(0, 66, 120, 0.10);
}

.panel-heading h2 {
  font-family: var(--font-display);
  font-size: 1.55rem;
  color: var(--g26-navy);
  margin: 0;
}

/* Headings a user can insert into a section's own BBCode content (the
   admin WYSIWYG's H1/H2/H3 buttons), as distinct from .panel-heading h2 --
   the section's own fixed title (e.g. "About Globe51") -- above. These
   render as real <h3>/<h4>/<h5> elements, not <h1>/<h2>/<h3> -- the page
   already uses h1 (site title) and h2 (.panel-heading's own fixed title)
   elsewhere, so BbCodeRenderer shifts content headings down two levels to
   keep the page's heading hierarchy semantically correct (see the mapping
   comment in BbCodeRenderer.cs). No specificity trick is needed here since
   .panel-heading's own heading is a real h2 and no longer shares a tag
   with these. */
.content-panel h3,
.content-panel h4,
.content-panel h5 {
  font-family: var(--font-display);
  color: var(--g26-navy);
}

.content-panel h3 {
  font-size: 1.8rem;
  font-weight: 700;
  margin: 1.5rem 0 0.6rem;
}

.content-panel h4 {
  font-size: 1.4rem;
  font-weight: 600;
  margin: 1.25rem 0 0.5rem;
}

.content-panel h5 {
  font-size: 1.15rem;
  color: var(--g26-blue);
  margin: 0 0 0.5rem;
}

.content-panel h3:first-child,
.content-panel h4:first-child,
.content-panel h5:first-child {
  margin-top: 0;
}

/* [center] has no bare HTML equivalent, so BbCodeRenderer wraps it in a
   plain <div class="bbcode-center"> instead -- this is the only rule that
   gives it an effect. */
.bbcode-center {
  text-align: center;
}

.content-panel p,
.content-panel li {
  line-height: 1.7;
  font-size: 1rem;
}

.materials-list {
  list-style: disc;
  padding-left: 1.25rem;
  line-height: 2;
}

.materials-list::marker,
.materials-list li::marker {
  color: var(--g26-blue);
}

.materials-list a {
  color: var(--g26-blue);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 106, 193, 0.35);
}

.materials-list a:hover {
  border-bottom-color: var(--g26-blue);
}

.placeholder-copy {
  color: var(--g26-muted);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-width: 480px;
  margin: 1.5rem auto 0;
}

.contact-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--g26-text);
}

    .contact-field.contact-second {
        display: none;
    }

    .contact-field input,
    .contact-field textarea {
        padding: 0.65rem 0.85rem;
        font-size: 1rem;
        font-family: var(--font-body);
        font-weight: 400;
        color: var(--g26-text);
        border: 1px solid rgba(0, 66, 120, 0.2);
        border-radius: 8px;
        box-sizing: border-box;
    }

.contact-field input:focus,
.contact-field textarea:focus {
  outline: none;
  border-color: var(--g26-blue);
  box-shadow: 0 0 0 3px rgba(0, 106, 193, 0.15);
}

.contact-field textarea {
  resize: vertical;
  min-height: 120px;
  font-family: inherit;
}

.contact-submit {
  align-self: flex-end;
  padding: 0.7rem 1.5rem;
  font-size: 1rem;
  font-weight: 600;
  font-family: inherit;
  color: #ffffff;
  background: var(--g26-blue);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s ease;
}

.contact-submit:hover {
  background: #005397;
}

/* Nav collapses to a hamburger below this width -- picked wider than the
   576px breakpoint further down, since it's the four text links (not
   just the logo/title) that run out of room first. */
@media (max-width: 768px) {
  .nav-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 40px;
    height: 40px;
  }

  .nav-toggle-bar {
    display: block;
    width: 22px;
    height: 2px;
    border-radius: 1px;
    background: var(--g26-navy);
    transition: transform 0.2s ease, opacity 0.2s ease;
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
    opacity: 0;
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }

  /* Slide-in drawer from the right, toggled open by site.js -- same
     pattern as the admin panel's own .admin-side-nav/.admin-nav-scrim,
     mirrored here for consistency. Off-screen by default (translateX),
     rather than hidden by size, so it can animate in as a whole panel
     over the page instead of unfurling as a dropdown. */
  .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: 360px;
    max-width: 90vw;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: #ffffff;
    box-shadow: -6px 0 24px rgba(0, 66, 120, 0.18);
    padding: 4.5rem 0 1.5rem;
    transform: translateX(100%);
    transition: transform 0.25s ease;
    z-index: 30;
    box-sizing: border-box;
  }

  .site-nav.open {
    transform: translateX(0);
  }

  /* Dims the rest of the page (header included) while the drawer is
     open, and doubles as the click-outside-to-close target (site.js). */
  .nav-scrim.open {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(15, 32, 51, 0.35);
    z-index: 20;
  }

  .nav-item {
    width: 100%;
    padding: 0.9rem 1.5rem;
    text-align: left;
    border-bottom: 1px solid rgba(0, 66, 120, 0.08);
  }

  /* The underline indicator assumes an inline text link with room either
     side of it -- against a full-width list row a soft fill reads better
     for "this is the open section" than a 2px underline would. */
  .nav-item.active::after {
    display: none;
  }

  .nav-item.active {
    background: var(--g26-navy-soft);
  }
}

@media (max-width: 576px) {
  .site-header {
    padding: 1rem;
    gap: 1rem;
  }

  .site-header-brand {
    gap: 0.75rem;
  }

  .site-logo {
    height: 48px;
  }

  .site-title {
    font-size: 1.35rem;
  }

  .hero-wrap {
    padding: 0 1rem;
    height: clamp(120px, calc(100vh - 360px), 380px);
  }

  .hero-tagline {
    padding: 1.1rem 1.25rem 0.25rem;
  }

  .hero-tagline-heading {
    font-size: 1.4rem;
  }

  .hero-tagline-subheading {
    font-size: 0.75rem;
  }

  .hero-caption {
    right: 1rem;
    bottom: 1rem;
    max-width: 80%;
    font-size: 1rem;
  }

  .site-content {
    padding: 0 1.25rem;
  }

  body.has-active .site-content {
    padding: 1rem 1.25rem 2rem;
  }

  .content-panel {
    padding: 1.5rem 1.5rem 1.75rem;
  }
}
