/* ============================================================
   Site header — German Power Solutions

   Selector strategy: every menu rule binds to WordPress's own
   wp_nav_menu() classes (.menu-item, .sub-menu,
   .menu-item-has-children, .current-menu-item) so the same CSS
   serves this static build and the eventual PHP theme with no
   edits. Only wrappers use gps- BEM names.

   Colour use is restricted to the four palette colours plus the
   listed neutrals, and to the deck's approved contrast pairings.
   ============================================================ */

/* .gps-sprite moved to base.css -- four sections emit one, not just this. */
.gps-ico{width:1.125rem;height:1.125rem;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}

/* overflow-x:clip is a backstop, not the mechanism. header.js measures each
   dropdown and adds .is-flipped when it would cross the right edge; this
   stops a closed panel widening the page in the window before that runs, or
   at all if the script fails. `clip` is the one overflow value that lets the
   other axis stay visible, so the mega panel still drops below the header.
   Browsers without `clip` (Safari < 16) drop the declaration and fall back
   to the JS path, which is the behaviour we had before. */
.gps-hdr{position:relative;z-index:50;background:var(--gps-white);
  overflow-x:clip;overflow-y:visible}

/* ---------- (a) Utility strip ---------- */
.gps-hdr__top{background:var(--grey-100);color:var(--ink);
  border-bottom:1px solid rgba(17,17,17,.08)}
.gps-hdr__top-inner{display:flex;align-items:center;justify-content:space-between;
  gap:var(--sp-5);min-height:2.75rem;flex-wrap:wrap}

.gps-hdr__contact{display:flex;align-items:center;gap:var(--sp-6);flex-wrap:wrap}
.gps-hdr__contact-link{display:inline-flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-sm);font-weight:var(--fw-med);color:var(--ink);
  padding-block:var(--sp-2);
  transition:color var(--dur-fast) var(--ease)}
.gps-hdr__contact-link:hover{color:var(--gps-red)}
.gps-hdr__contact .gps-ico{color:var(--gps-red)}

.gps-hdr__social{display:flex;align-items:center;gap:var(--sp-1)}
.gps-hdr__social a{display:inline-flex;align-items:center;justify-content:center;
  width:2.25rem;height:2.25rem;color:var(--ink);
  transition:color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease)}
.gps-hdr__social a:hover{background:var(--gps-red);color:var(--gps-white)}

/* ---------- (b) Main bar ---------- */
.gps-hdr__main{background:var(--gps-white);
  border-bottom:3px solid var(--gps-black)}
.gps-hdr__bar{display:flex;align-items:center;gap:var(--sp-5);
  min-height:5.25rem}

/* ---------- Brand lockup ---------- */
.gps-brand{display:inline-flex;align-items:center;gap:var(--sp-3);flex:none}
.gps-brand__mark{width:2.5rem;height:2.5rem;flex:none}
/* Customizer logo, when one is set. inc/setup.php registers custom-logo
   at 44x220 with flex-height AND flex-width, so the client can upload any
   ratio and header.php renders that attachment at 'full' size inside this
   same anchor, in place of the mark + lockup. 'full' is the operative word:
   a 1600px-wide upload arrives 1600px wide, and .gps-hdr__bar is a flex row
   that still has to hold the nav and the search button, so nothing below is
   cosmetic. Height is the constraint and width is left free, the same way
   the theme registers it -- a hard crop would slice a wordmark.
   2.75rem is the registered 44px, which is also the 44px tap-target unit
   the rest of this header is built on, and it clears the 4rem mobile bar
   (--gps-hdr-bar-h) as well as the 5.25rem desktop one.
   min-width:0 because a flex item's automatic minimum size is its content
   width: without it a wide logo refuses to shrink at 320 and pushes the
   bar past the viewport. height:auto + width:auto keep the ratio while it
   shrinks; object-fit only bites if the width/height attributes WordPress
   emits are ever pinned in both axes, and costs nothing when they are not. */
.gps-brand__logo{display:block;min-width:0;
  width:auto;height:auto;max-width:13.75rem;max-height:2.75rem;
  object-fit:contain;object-position:left center}
.gps-brand__lockup{display:flex;flex-direction:column;align-items:flex-start;gap:.2rem}
.gps-brand__word{
  font-family:var(--font-head);font-weight:var(--fw-black);
  font-size:clamp(1.5rem,2.4vw,1.875rem);line-height:.9;
  letter-spacing:-.02em;text-transform:uppercase;
  color:var(--gps-red);                      /* 5.15:1 on white — AA */
}
.gps-brand__descriptor{
  display:block;background:var(--gps-yellow);color:var(--gps-black); /* 12.66:1 */
  padding:.18rem var(--sp-2);
  font-family:var(--font-head);font-weight:var(--fw-med);
  font-size:clamp(.5rem,.72vw,.625rem);line-height:1.25;
  letter-spacing:.25em;text-transform:uppercase;
}

/* ---------- Primary nav (desktop) ---------- */
.gps-hdr__nav{flex:1 1 auto;min-width:0;display:flex;justify-content:flex-end}
.gps-menu{display:flex;align-items:center}
.gps-menu > .menu-item{position:relative}
/* The link and its disclosure button are inline-level siblings, so by
   default they align on the text baseline and the chevron lands ~5px above
   the link's centre. Flex alignment centres them. The submenu is absolutely
   positioned, so it stays out of this flow. Desktop only: the mobile block
   below gives parent rows their own grid. */
@media (width >= 64rem){
  .gps-menu > .menu-item{display:flex;align-items:center}
}
.gps-menu > .menu-item > a{
  display:inline-flex;align-items:center;gap:.35rem;
  padding:var(--sp-3) var(--sp-4);
  font-family:var(--font-head);font-size:var(--fs-sm);font-weight:var(--fw-med);
  color:var(--ink);white-space:nowrap;
  transition:color var(--dur-fast) var(--ease)}
.gps-menu > .menu-item > a::after{
  content:"";position:absolute;left:var(--sp-4);right:var(--sp-4);bottom:.55rem;
  height:3px;background:var(--gps-red);
  transform:scaleX(0);transform-origin:left center;
  transition:transform var(--dur) var(--ease)}
.gps-menu > .menu-item:hover > a,
.gps-menu > .menu-item:focus-within > a,
.gps-menu > .current-menu-item > a{color:var(--gps-red)}
.gps-menu > .menu-item:hover > a::after,
.gps-menu > .menu-item:focus-within > a::after,
.gps-menu > .current-menu-item > a::after{transform:scaleX(1)}

/* Submenu disclosure button — sits beside the parent link so the link
   itself stays a real, followable link (WP parents are linkable too). */
.gps-menu__toggle{display:inline-flex;align-items:center;justify-content:center;
  width:1.75rem;height:1.75rem;margin-inline-start:-.5rem;color:var(--ink);
  transition:transform var(--dur) var(--ease),color var(--dur-fast) var(--ease)}
.gps-menu__toggle .gps-ico{width:1rem;height:1rem}
.menu-item-has-children:hover > .gps-menu__toggle,
.gps-menu__toggle[aria-expanded="true"]{color:var(--gps-red)}
.gps-menu__toggle[aria-expanded="true"]{transform:rotate(180deg)}

/* ---------- Dropdowns ---------- */
.gps-menu .sub-menu{
  position:absolute;top:100%;left:0;z-index:20;
  min-width:17rem;padding:var(--sp-3) 0;
  background:var(--gps-white);
  border:1px solid rgba(17,17,17,.12);
  border-top:3px solid var(--gps-red);
  opacity:0;visibility:hidden;transform:translateY(.5rem);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),
             visibility 0s linear var(--dur)}
.gps-menu .menu-item-has-children:hover > .sub-menu,
.gps-menu .menu-item-has-children.is-open > .sub-menu{
  opacity:1;visibility:visible;transform:none;
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),visibility 0s}
.gps-menu .sub-menu .menu-item > a{
  display:block;padding:var(--sp-2) var(--sp-5);
  font-size:var(--fs-sm);font-weight:var(--fw-reg);color:var(--ink);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.gps-menu .sub-menu .menu-item > a:hover{background:var(--grey-100);color:var(--gps-red)}

/* A dropdown near the right edge is anchored to its parent's right side
   instead of its left. Which items need this depends on menu length and
   label text — both editable in WordPress — so header.js measures and
   applies .is-flipped rather than us hardcoding "the last two items". */
.gps-menu .sub-menu.is-flipped{left:auto;right:0}

/* Mega panel — six groups, anchored to the header not to the list item.
   The selector must out-specify `.gps-menu > .menu-item{position:relative}`
   (0,2,0); a bare `.gps-menu__mega` (0,1,0) loses and the panel ends up
   hanging off the right edge of the page. Width is a % of .gps-hdr, not
   100vw, because 100vw includes the scrollbar and would overflow again. */
.gps-menu > .menu-item.gps-menu__mega{position:static}
/* Centred with `left:0;right:0;margin-inline:auto`, NOT translateX(-50%).
   Auto margins centre the panel during layout, so its horizontal position
   no longer depends on a compositor-applied transform — the enter/exit
   animation only moves it vertically. */
.gps-menu__mega > .gps-mega{
  left:0;right:0;margin-inline:auto;transform:translateY(.5rem);
  width:min(var(--container),calc(100% - 2rem));
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--sp-5) var(--sp-6);padding:var(--sp-6)}
.gps-menu__mega:hover > .gps-mega,
.gps-menu__mega.is-open > .gps-mega{transform:none}
.gps-mega__head{
  margin:0 0 var(--sp-2);padding-bottom:var(--sp-2);
  border-bottom:2px solid var(--gps-yellow);
  font-family:var(--font-head);font-size:var(--fs-xs);font-weight:var(--fw-black);
  letter-spacing:.14em;text-transform:uppercase;color:var(--gps-black)}
.gps-mega__group > ul{display:grid;gap:.1rem}
.gps-mega__group .menu-item > a{padding-inline:0}

@media (64rem <= width <= 81.25rem){
  .gps-menu > .menu-item > a{padding-inline:var(--sp-2);font-size:var(--fs-xs)}
  .gps-menu > .menu-item > a::after{left:var(--sp-2);right:var(--sp-2)}
  .gps-hdr__bar{gap:var(--sp-3)}
  .gps-menu__mega > .gps-mega{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* The narrow-desktop tuning above re-declares the panel as three columns.
   It has to stay for touch devices in that band, and it has to LOSE to the
   flyout on pointer devices — so the flyout block follows it rather than
   preceding it. Source order is the whole mechanism: both rules carry the
   same specificity, and at 1024-1300px with a fine pointer both match. */
/* ============================================================
   Mega panel, flyout shape (the reference's arrangement)

   One category's items at a time: the categories stack down a left rail,
   and the hovered or focused one projects its list into the pane beside
   it. The all-at-once grid above stays as the fallback, and that is not
   laziness -- it is what touch gets, because a flyout that only opens on
   hover has no way to open on a device with no hover.

   Hence the media query: (hover:hover) and (pointer:fine). A tablet at
   1200px matches the width but not the pointer, and keeps the grid where
   every category is already visible and tappable.

   The right pane is absolutely positioned rather than placed in a grid
   cell, so the group <li> can stay one element containing both its head
   and its list. Using display:contents to break the <li> apart would put
   them in separate grid cells, but drops the element from the
   accessibility tree in browsers that still ship that bug.

   NO overflow-y here. Per CSS Overflow 3 setting one axis to auto forces
   the other to auto as well, which would turn the panel into a scroll
   container and clip the very pane it is projecting. The panel is sized
   to its tallest list instead. */
@media (width >= 64rem) and (hover:hover) and (pointer:fine){
  .gps-menu__mega > .gps-mega{
    --mega-rail:15rem;
    /* NO position here. The panel is already position:absolute from
       .gps-menu .sub-menu, which makes it a containing block for the
       panes below all by itself. Declaring position:relative instead
       pulls it back into normal flow, where it collapses to the width of
       its left rail and the pane column resolves to 0px. */
    grid-template-columns:var(--mega-rail) minmax(0,1fr);
    align-content:start;
  }

  /* Every group occupies the left rail; only their lists move. */
  .gps-mega__group{grid-column:1}

  .gps-mega__head{
    margin:0;
    padding:var(--sp-2) var(--sp-3);
    border-bottom:0;
    border-inline-start:3px solid transparent;
    letter-spacing:var(--tr-snug);
    font-size:var(--fs-sm);
    text-transform:none;
    transition:background var(--dur-fast) var(--ease),
               border-color var(--dur-fast) var(--ease);
  }
  .gps-mega__head a{display:block;color:inherit}

  .gps-mega__group:hover > .gps-mega__head,
  .gps-mega__group:focus-within > .gps-mega__head{
    background:var(--grey-100);
    border-inline-start-color:var(--gps-red);
  }

  /* The right pane. Every list is stacked in the same place; exactly one
     is displayed at a time. */
  .gps-mega__group > ul{
    position:absolute;
    inset-block:var(--sp-6);
    inset-inline-start:calc(var(--mega-rail) + var(--sp-6));
    inset-inline-end:var(--sp-6);
    display:none;
    align-content:start;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:.1rem var(--sp-5);
  }
  .gps-mega__group:hover > ul,
  .gps-mega__group:focus-within > ul{display:grid}

  /* With nothing hovered or focused the pane would be empty, and an empty
     half-panel reads as a broken menu. The first category stands in until
     the pointer picks one. :not() on the panel rather than a JS-applied
     class, so it is correct on the very first frame the panel opens. */
  .gps-menu__mega > .gps-mega:not(:hover):not(:focus-within) .gps-mega__group:first-child > ul{display:grid}

  /* A rail long enough to outrun its own pane still has to fit: the panel
     grows with the rail, and the pane is pinned to the panel's block box,
     so the two can never disagree about height. */
  .gps-menu__mega > .gps-mega{min-block-size:16rem}
}


/* ---------- Actions ---------- */
.gps-hdr__actions{display:flex;align-items:center;gap:var(--sp-1);flex:none}
.gps-hdr__iconbtn{display:inline-flex;align-items:center;justify-content:center;
  width:2.75rem;height:2.75rem;color:var(--ink);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.gps-hdr__iconbtn .gps-ico{width:1.25rem;height:1.25rem}
.gps-hdr__iconbtn:hover{background:var(--gps-black);color:var(--gps-yellow)}
.gps-hdr__burger{display:none}
.gps-hdr__burger-close{display:none}
.gps-hdr__burger[aria-expanded="true"] .gps-hdr__burger-open{display:none}
.gps-hdr__burger[aria-expanded="true"] .gps-hdr__burger-close{display:block}

/* ---------- Search panel ---------- */
.gps-search{background:var(--gps-black);border-bottom:3px solid var(--gps-yellow)}
.gps-search__form{display:flex;align-items:center;gap:var(--sp-3);
  padding-block:var(--sp-4)}
.gps-search__field{
  flex:1 1 auto;min-width:0;height:3.25rem;padding:0 var(--sp-4);
  background:var(--gps-white);color:var(--ink);
  border:3px solid var(--gps-white);border-radius:var(--radius-0);
  font:inherit;font-size:var(--fs-base)}
.gps-search__field::placeholder{color:#5a5a5a}
.gps-search__submit{flex:none}
.gps-search__close{color:var(--gps-white)}
.gps-search__close:hover{background:var(--gps-yellow);color:var(--gps-black)}

/* ---------- Scrim (handheld nav backdrop) ----------
   z-index 40 puts it under .gps-hdr (50), so the pinned bar and the
   panel hanging off it stay bright and clickable while everything
   below is dimmed. */
.gps-hdr__scrim{position:fixed;inset:0;z-index:40;background:rgba(17,17,17,.6)}

/* ============================================================
   Mobile / tablet — pinned bar + slide-down nav panel

   The reference drops a full-width panel from underneath a pinned
   white bar; it does not slide a drawer in from the side. This block
   rebuilds ours the same way.

   Nothing below renames a class, a data attribute or an aria hook.
   header.js still toggles .is-open on [data-hdr-nav], still un-hides
   [data-hdr-scrim], still puts .gps-no-scroll on <body>, and still
   drives the accordions through li.is-open / .gps-menu__toggle.
   The panel keeps `visibility:hidden` while closed so its links stay
   out of the tab order, which is what the focus trap in header.js
   assumes when it filters on offsetParent.
   ============================================================ */
@media (width < 64rem){

  /* Three heights the rest of this block is built on. They sit on
     :root rather than .gps-hdr because <html> needs the bar height for
     scroll-padding and cannot inherit from its own descendant. */
  :root{
    --gps-hdr-strip-h:2.75rem;   /* utility strip: exactly one 44px row */
    --gps-hdr-bar-h:4rem;        /* main bar: the reference measures 64px */
    /* +3px for the black rule under the bar */
    --gps-hdr-h:calc(var(--gps-hdr-strip-h) + var(--gps-hdr-bar-h) + 3px);
  }

  /* The whole header is the sticky element, pulled up by exactly the
     strip's height so only the white bar ends up pinned. Sticking
     .gps-hdr__main on its own is not possible: its containing block is
     .gps-hdr, which is no taller than the bar itself, so it would have
     nowhere to travel and would never stick at all. */
  .gps-hdr{position:sticky;top:calc(-1 * var(--gps-hdr-strip-h))}

  /* No strip, no pull-up. header.php omits the utility strip entirely when
     there is no email, no phone and no social profile to put in it, and the
     negative top above is measured against a strip that is then not there --
     it would drag the white bar 44px off the top of the viewport and keep it
     there for the whole scroll, clipping the logo and half the nav.
     --gps-hdr-h is re-stated for the same reason: the mobile drawer sizes
     itself against it, and it would otherwise reserve room for a strip that
     does not exist. */
  .gps-hdr--nostrip{
    --gps-hdr-h:calc(var(--gps-hdr-bar-h) + 3px);
    top:0;
  }

  /* base.css parks in-page anchors 32px from the top, which a pinned
     64px bar would cover. The compensation lives next to its cause. */
  html{scroll-padding-top:calc(var(--gps-hdr-bar-h) + var(--sp-3))}

  /* ---------- (a) Utility strip: one fixed row ----------
     The sticky offset above is the exact negative of this height, so
     the strip must never wrap. It previously stacked into three centred
     rows — 154px at 375px, two thirds of the header, before the hero
     had even started.

     The hairline moves into an inset shadow so it stops eating a pixel
     of the row: with a real border the strip is 44px but its contents
     get 43, which put every link in it one pixel under the touch-target
     floor for no visible gain. */
  .gps-hdr__top{height:var(--gps-hdr-strip-h);border-bottom:0;
    box-shadow:inset 0 -1px 0 rgba(17,17,17,.08)}
  .gps-hdr__top-inner{
    flex-wrap:nowrap;justify-content:space-between;align-items:stretch;
    height:100%;min-height:0;padding-block:0;gap:var(--sp-3)}

  .gps-hdr__contact{width:auto;min-width:0;flex-wrap:nowrap;
    align-items:stretch;gap:var(--sp-3)}
  .gps-hdr__contact li{display:flex;min-width:0}
  /* Stretching the link to the full 44px row is what turns a 36px-tall
     text link into a legal touch target without adding any height. */
  .gps-hdr__contact-link{font-size:var(--fs-xs);padding-block:0;
    min-width:0;white-space:nowrap}
  /* Last line of defence: a client with a longer phone number or address
     ellipsises instead of pushing the socials past the right edge. */
  .gps-hdr__contact-link span{min-width:0;overflow:hidden;text-overflow:ellipsis}

  /* 44x44 and butted together. Three 36px icons with a 4px gap were both
     under the touch-target floor and, at 116px, barely narrower. */
  .gps-hdr__social{width:auto;flex:none;justify-content:flex-end;gap:0}
  .gps-hdr__social a{width:2.75rem;height:2.75rem}

  /* ---------- (b) Main bar ---------- */
  /* The nav is taken out of flow below, so the bar loses the flex:1
     spacer that used to push the actions right. space-between restores
     it and keeps the burger hard against the gutter. */
  .gps-hdr__bar{min-height:var(--gps-hdr-bar-h);gap:var(--sp-3);
    justify-content:space-between}
  .gps-brand{min-height:2.75rem}          /* logo is a link: 44px tall */
  .gps-hdr__burger{display:inline-flex}

  /* ---------- The slide-down panel ----------
     Anchored to the bottom of .gps-hdr, so it travels with the pinned
     bar and re-seats itself if the search panel opens above it.
     .gps-hdr's overflow-x:clip / overflow-y:visible pair is what lets a
     full-width child hang below the header without widening the page —
     the same mechanism the desktop mega panel already relies on. */
  .gps-hdr__nav{
    position:absolute;left:0;right:0;top:100%;z-index:45;
    width:auto;display:block;flex:none;
    /* Worst case is the page at scroll top, where the panel starts
       --gps-hdr-h down the viewport; sized for that, it never runs off
       the bottom and scrolls internally instead. vh first for engines
       without dvh. */
    max-height:calc(100vh - var(--gps-hdr-h));
    max-height:calc(100dvh - var(--gps-hdr-h));
    background:var(--gps-black);color:var(--gps-white);   /* 18.88:1 */
    border-bottom:3px solid var(--gps-yellow);
    padding-block:var(--sp-2) var(--sp-5);
    overflow-y:auto;overscroll-behavior:contain;
    transform:none;                       /* retires the off-canvas slide */
    opacity:0;visibility:hidden;
    /* The unroll. clip-path is the only property that reveals top-down
       without squashing the type or overlapping the bar on the way in;
       an engine that does not animate it still gets opacity+visibility,
       so the panel is never stuck open. */
    -webkit-clip-path:inset(0 0 100% 0);clip-path:inset(0 0 100% 0);
    transition:clip-path var(--dur) var(--ease),opacity var(--dur) var(--ease),
               visibility 0s linear var(--dur)}
  .gps-hdr__nav.is-open{
    opacity:1;visibility:visible;
    -webkit-clip-path:inset(0 0 0 0);clip-path:inset(0 0 0 0);
    transition:clip-path var(--dur) var(--ease),opacity var(--dur) var(--ease),
               visibility 0s}

  .gps-menu{display:block}
  .gps-menu > .menu-item{border-bottom:1px solid rgba(255,255,255,.14)}
  .gps-menu > .menu-item:last-child{border-bottom:0}
  /* Rows are indented to --container-pad so the menu lines up with the
     page gutter underneath it, the way the reference panel does. */
  .gps-menu > .menu-item > a,
  .gps-menu .sub-menu .menu-item > a{
    display:block;padding:var(--sp-3) var(--container-pad);
    font-size:var(--fs-base);font-weight:var(--fw-med);
    color:var(--gps-white);white-space:normal}
  .gps-menu > .menu-item > a::after{display:none}
  /* :focus-within must be in this group. Without it the desktop rule
     above — same three-class shape, one pseudo-class heavier — repaints
     the focused row German Red, and red on black is 3.66:1. header.js
     focuses the first row the instant the panel opens, so that was the
     default state of the open menu, not an edge case. */
  .gps-menu > .menu-item:hover > a,
  .gps-menu > .menu-item:focus-within > a,
  .gps-menu > .current-menu-item > a{color:var(--gps-yellow)}  /* 12.66:1 */

  /* Parent rows: link + disclosure sit on one line */
  .gps-menu > .menu-item-has-children{
    display:grid;grid-template-columns:1fr auto;align-items:center}
  .gps-menu > .menu-item-has-children > .sub-menu{grid-column:1/-1}
  .gps-menu__toggle{width:3.25rem;height:3.25rem;margin:0;
    color:var(--gps-white);border-inline-start:1px solid rgba(255,255,255,.14)}
  .gps-menu__toggle .gps-ico{width:1.25rem;height:1.25rem}
  /* Same contrast trap as the row links: the desktop :hover rule is red,
     and a tapped toggle keeps :hover on touch until you tap elsewhere. */
  .menu-item-has-children:hover > .gps-menu__toggle,
  .gps-menu__toggle[aria-expanded="true"]{color:var(--gps-yellow)}

  /* Submenus become in-flow accordions */
  .gps-menu .sub-menu,
  .gps-menu__mega > .gps-mega{
    position:static;transform:none;width:auto;
    /* margin-inline:auto survives from the desktop mega rule, and auto
       margins on a grid item suppress justify-self:stretch — which is
       why the panel used to shrink to its longest label and float in
       the middle of the row instead of filling it. */
    margin-inline:0;
    display:none;opacity:1;visibility:visible;
    background:rgba(255,255,255,.05);border:0;
    padding:var(--sp-2) 0;min-width:0;
    grid-template-columns:1fr;gap:var(--sp-3)}
  .gps-menu .menu-item-has-children:hover > .sub-menu{display:none}
  .gps-menu .menu-item-has-children.is-open > .sub-menu{display:block}
  /* Four classes, to out-specify the display:block on the line above —
     without it the mega renders as a plain block and the six groups run
     together with no gap between them. */
  .gps-menu .menu-item-has-children.gps-menu__mega.is-open > .gps-mega{display:grid}
  .gps-menu .sub-menu .menu-item > a{
    padding-block:var(--sp-3);
    padding-inline-start:calc(var(--container-pad) + var(--sp-4));
    font-size:var(--fs-sm);font-weight:var(--fw-reg);
    color:rgba(255,255,255,.88)}
  .gps-menu .sub-menu .menu-item > a:hover{background:rgba(255,255,255,.08);
    color:var(--gps-yellow)}
  .gps-mega__head{margin-inline:var(--container-pad);color:var(--gps-yellow);
    border-bottom-color:rgba(255,206,0,.45)}
  .gps-mega__group .menu-item > a{
    padding-inline-start:calc(var(--container-pad) + var(--sp-4))}

  .gps-search__form{flex-wrap:wrap}
  .gps-search__field{flex:1 1 100%;order:1}
  .gps-search__submit{order:2;flex:1 1 auto}
  .gps-search__close{order:3}
}

/* ---------- Utility strip: dropping labels as the row runs out ----------
   Measured, not guessed. At 375px the row has 335px to play with and the
   address alone renders 230px of it, so the envelope has to carry the
   link on its own. The <span> is clipped rather than removed, so the
   link keeps "info@germanpowersolutions.example" as its accessible name
   and nothing is lost to a screen reader. */
@media (width <= 40rem){
  /* flex:none, or the 44px square is the first thing flexbox shaves when
     the row runs 2px short at 361 — and it is the one item in the row
     that has no slack to give. The phone label absorbs it instead. */
  .gps-hdr__contact li:first-child{flex:none}
  .gps-hdr__contact li:first-child .gps-hdr__contact-link{
    width:2.75rem;justify-content:center}
  .gps-hdr__contact li:first-child .gps-hdr__contact-link span{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
}
/* 360px and below: the number goes the same way. Icon + number + three
   44px socials comes to 305px against 280px of row at 320px. */
@media (width <= 22.5rem){
  .gps-hdr__contact li:last-child{flex:none}
  .gps-hdr__contact li:last-child .gps-hdr__contact-link{
    width:2.75rem;justify-content:center}
  .gps-hdr__contact li:last-child .gps-hdr__contact-link span{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
}

@media (width < 30rem){
  .gps-brand__mark{width:2rem;height:2rem}
  /* Same step the mark takes, for the same reason: the bar at 375 has to
     fit the brand, the search button and the hamburger on one row. Width
     follows from the ratio, so a wordmark gets proportionally narrower
     rather than letterboxed. */
  .gps-brand__logo{max-height:2rem}
  .gps-brand__word{font-size:1.25rem}
  .gps-brand__descriptor{font-size:.4375rem;letter-spacing:.2em}
}

/* Body lock while the panel is open. Still load-bearing: without it the
   page scrolls behind an open panel and the pinned bar — and therefore
   the panel hanging off it — slides away under the user's thumb. */
body.gps-no-scroll{overflow:hidden}

@media (prefers-reduced-motion:reduce){
  .gps-hdr__nav,.gps-menu .sub-menu,.gps-menu__toggle{transition:none}
}

/* ============================================================
   Escape dismissal + toast
   These rules must stay LAST in the file. `.is-dismissed` has the
   same specificity as the :hover / :focus-within open rules above,
   so source order is what lets it win — otherwise Escape would be
   undone the instant focus returned to the parent link.
   ============================================================ */
@media (width >= 64rem){
  .gps-menu .menu-item-has-children.is-dismissed > .sub-menu{
    opacity:0;visibility:hidden;transform:translateY(.5rem);
    transition:opacity var(--dur-fast) var(--ease),visibility 0s linear var(--dur-fast)}
  .gps-menu__mega.is-dismissed > .gps-mega{transform:translateY(.5rem)}
}

.gps-toast{
  /* Centred with auto margins, not left:50%. A shrink-to-fit fixed box
     anchored at left:50% can only ever be half the viewport wide, so its
     max-width never binds and the toast renders as a narrow column on
     phones. Insetting both edges gives it the full width to shrink from. */
  position:fixed;left:0;right:0;bottom:var(--sp-6);z-index:200;
  width:fit-content;margin-inline:auto;
  transform:translateY(1rem);
  max-width:min(30rem,calc(100% - 2rem));
  padding:var(--sp-3) var(--sp-5);
  background:var(--gps-black);color:var(--gps-white);
  font-size:var(--fs-sm);font-weight:var(--fw-med);text-align:center;
  border-left:4px solid var(--gps-yellow);
  opacity:0;pointer-events:none;
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
.gps-toast.is-on{opacity:1;transform:none}
