/* ============================================================
   German Power Solutions — Contact page
   Loaded by inc/enqueue.php on the Contact template only.

   Laid out on the reference's contact page:

     1. the map, full bleed, directly under the header, 432px
        tall at every width;
     2. one row beneath it, never wider than the reference's
        1160px: office cards in two columns across the left two
        thirds, the enquiry card in the last third;
     3. white cards on the white page, lifted by a soft shadow
        rather than drawn with a border, their detail rows led by
        round icon chips.

   Below 64rem the row stacks, offices first and the form last,
   which is the order the reference itself uses on a phone.

   What differs from the reference is small and deliberate: the
   map waits behind a consent gate instead of loading on sight
   (see template-parts/contact-map.php); the palette, the corner
   radius and the button are this site's rather than the
   reference's navy and gold pill; and the form keeps real labels,
   hidden, behind its placeholders.

   Depends on tokens.css and base.css for the palette, .container,
   .section, .section-head, .btn and .visually-hidden, and on
   header.css for the base .gps-ico geometry (it loads on every
   page). Two of those are restated here on purpose: the
   .visually-hidden geometry for the form labels, because that
   class is !important and a failed field has to undo it; and the
   primary button for a form plugin's submit, which cannot be
   given our classes. Breakpoints are the ladder's own rungs, 48rem
   and 64rem -- see the top of base.css.
   ============================================================ */

/* The enquiry card carries the tokens too, because it is not only on
   the Contact page: a sub-category page puts the same card in its
   sidebar, outside .gps-contact. A var() that resolves to nothing
   makes the whole `border` shorthand invalid, so without this the
   fields there lost their edges and the card its shadow. */
.gps-contact,
.gps-contact__map,
.gps-contact__enquiry{
  /* The reference's card shadows: a wide, faint halo instead of a
     drop, so the cards read as lifted without an outline. The
     office cards take the lighter one, as they do there. */
  --gps-contact-shadow:0 1px 1.2rem rgba(17,17,17,.10);
  --gps-contact-shadow-soft:0 1px 1.2rem rgba(17,17,17,.07);
  /* Field edges. --grey-300 is 1.61:1 on white, too faint to find
     an empty field by (WCAG 1.4.11 asks 3:1 of a control's edge);
     this is the lightest black that clears it, at 3.1:1. */
  --gps-contact-line:rgba(17,17,17,.46);
  /* The map placeholder's ground: a black tint a shade under
     --grey-100, so that white streets show on it. */
  --gps-map-ground:rgba(17,17,17,.09);
}

/* ---- Map band ----------------------------------------------
   Full bleed, straight under the header: the reference's first
   thing on the page. 27rem is its 432px, held at every width as
   the reference holds it, and reserved before the iframe exists
   so that loading the map moves nothing below it.

   Until then the band is a light street plan -- an original
   pattern, drawn in CSS so the placeholder costs no request --
   under a small card that carries the consent note and the
   button. A plain grey rectangle across the top of the page
   would read as a map that failed to load. */
.gps-map{
  position:relative;
  display:grid;
  place-items:center;
  block-size:27rem;
  padding:var(--sp-5);
  overflow:hidden;
  background:
    /* two arterial roads and one avenue cutting across the grid */
    linear-gradient(102deg,transparent calc(38% - .45rem),var(--gps-white) calc(38% - .4rem) calc(38% + .4rem),transparent calc(38% + .45rem)),
    linear-gradient(12deg,transparent calc(64% - .4rem),var(--gps-white) calc(64% - .35rem) calc(64% + .35rem),transparent calc(64% + .4rem)),
    linear-gradient(147deg,transparent calc(57% - .3rem),var(--gps-white) calc(57% - .25rem) calc(57% + .25rem),transparent calc(57% + .3rem)),
    /* the street grid, turned off the axis the way real streets are */
    repeating-linear-gradient(102deg,transparent 0 5.25rem,rgba(255,255,255,.85) calc(5.25rem + 1px) 5.5rem,transparent calc(5.5rem + 1px) 5.75rem),
    repeating-linear-gradient(12deg,transparent 0 3.75rem,rgba(255,255,255,.85) calc(3.75rem + 1px) 4rem,transparent calc(4rem + 1px) 4.25rem),
    var(--gps-map-ground);
}

.gps-map__gate{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--sp-4);
  inline-size:min(100%,25rem);
  padding:var(--sp-6) var(--sp-5);
  border-radius:var(--radius-tile);
  background:var(--gps-white);
  box-shadow:var(--gps-contact-shadow);
  /* Invisible, until Windows' high-contrast mode drops the shadow
     and the fill: then it is the card's only edge. */
  outline:1px solid transparent;
  text-align:center;
}

/* A map marker, in the flag's red. */
.gps-map__ico{
  width:2.25rem;
  height:2.25rem;
  color:var(--gps-red);
}

.gps-map__note{
  max-inline-size:34ch;
  margin:0;
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--grey-600);
  text-wrap:pretty;
}

/* .btn--primary turns white on hover, which is right on the dark
   grounds it was drawn for and makes it vanish on a white card. */
.gps-map__button:hover,
.gps-enquiry__submit:hover{
  background:var(--gps-black);
  border-color:var(--gps-black);
  color:var(--gps-white);
}

/* Both labels are Customizer strings, and .btn never wraps: a
   longer label than the shipped one would run out of a narrow card
   at 320px, or at 1024px where the form column is at its thinnest.
   Same remedy as the product page's contact buttons. */
.gps-map__button,
.gps-enquiry__submit{
  max-inline-size:100%;
  white-space:normal;
  overflow-wrap:anywhere;
  text-align:center;
}

/* What the script swaps in for the gate: the whole band. */
.gps-map__frame{
  position:absolute;
  inset:0;
  display:block;
  inline-size:100%;
  block-size:100%;
  border:0;
}
/* The script moves focus into the frame. The site's ring is drawn
   outside the element, and the frame fills a band that clips its
   overflow, so here the ring is drawn inside instead. .is-keyed is
   the script's mark for a map loaded from the keyboard, which
   Chrome does not count as :focus-visible (see contact.js); and
   with focus inside the map's own document, the frame element
   matches :focus-within rather than :focus. */
.gps-map__frame:focus-visible,
.gps-map__frame.is-keyed:focus-within{
  outline:4px solid var(--gps-black);
  outline-offset:-4px;
  box-shadow:none;
}

/* ---- The row under the map ---------------------------------
   The reference opens its row 58px under the map. .section's
   own top padding is the right rhythm under a page title, so it
   is only overridden when the map is what comes before. */
.gps-contact--map{padding-block-start:clamp(var(--sp-8),4vw,3.625rem)}

.gps-contact__intro{
  max-inline-size:60ch;
  margin:0 auto var(--sp-7);
  font-size:var(--fs-lg);
  line-height:var(--lh-body);
  color:var(--grey-600);
  text-align:center;
  text-wrap:pretty;
}

/* 2.1fr / 1fr is the reference's 761px of offices against a
   362px form. minmax(0,…) on both tracks and not just 1fr: a grid
   track's default minimum is auto, so one long unbroken word in
   an address -- a German street name will do it -- would push
   the track wider than its share and shove the form off the grid.

   One track below 64rem, with the form after the offices: the
   source order, which is also the order a screen reader and the
   tab key follow. */
.gps-contact__layout{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--sp-8);
  max-inline-size:72.5rem;
  margin-inline:auto;
}

@media (width >= 64rem){
  .gps-contact__layout{
    grid-template-columns:minmax(0,2.1fr) minmax(0,1fr);
    gap:var(--sp-7);
    align-items:start;
  }
  /* One office -- every install before its first Office post, when
     the card is built from Contact Details. Two thirds of the row
     for one card is a card, a blank column and then the form, so
     the two become an even pair in the middle instead. */
  .gps-contact__layout:has(.gps-office:only-child){
    grid-template-columns:repeat(2,minmax(0,1fr));
    max-inline-size:48rem;
  }
}

/* ---- Office cards ------------------------------------------
   Two columns from the tablet rung up, one below it. An explicit
   two rather than auto-fit, so that a wide tablet does not break
   into a third column the reference never has. 48px between rows,
   at every width, is the reference's 50px -- the same as the gap
   above the form once the row stacks. */
.gps-offices{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--sp-8) var(--sp-5);
  margin:0;
  padding:0;
}

@media (width >= 48rem){
  .gps-offices{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* A lone card takes the whole track; see the layout above. */
.gps-offices:has(> :only-child){grid-template-columns:minmax(0,1fr)}

/* Stretched to the tallest card in its row, so the cards in a row
   share an edge whatever each one holds. */
.gps-office{display:flex}

.gps-office__body{
  display:flex;
  flex-direction:column;
  inline-size:100%;
  padding:1.25rem;
  border-radius:var(--radius-tile);
  background:var(--gps-white);
  box-shadow:var(--gps-contact-shadow-soft);
  outline:1px solid transparent;   /* the edge in forced-colors mode */
  /* A German compound street name or a long trading name is one
     word that can be wider than a two-up card. */
  overflow-wrap:anywhere;
}

/* The place, in capitals as the reference sets it -- by CSS, so
   the office's title in wp-admin stays in ordinary case. */
.gps-office__place{
  margin:0 0 1.25rem;
  font-size:clamp(var(--fs-xl),1.75vw,1.5625rem);
  font-weight:var(--fw-bold);
  letter-spacing:var(--tr-snug);
  line-height:1.4;
  text-transform:uppercase;
  color:var(--gps-black);
}

.gps-office__company{
  margin:0 0 1.25rem;
  font-size:1.125rem;
  font-weight:var(--fw-bold);
  line-height:1.4;
  color:var(--gps-black);
}

/* One detail per row, led by its chip, in the reference's 18px on
   30px lines. align-items:start, not center: an address runs to
   several lines, and a chip centred on the whole block floats
   beside its middle line instead of its first. */
.gps-office__row{
  display:flex;
  align-items:start;
  gap:var(--sp-3);
  margin:0 0 var(--sp-4);
  font-size:1.125rem;
  line-height:1.875rem;
  color:var(--grey-600);
}
.gps-office__row > :last-child{min-inline-size:0}

.gps-office__chip{
  display:grid;
  place-items:center;
  flex:none;
  inline-size:1.625rem;
  block-size:1.625rem;
  /* (30px - 26px) / 2: centred on the first line, not the top. */
  margin-block-start:.125rem;
  border-radius:50%;
  background:var(--gps-black);
  color:var(--gps-white);
}
.gps-office__ico{
  width:.875rem;
  height:.875rem;
  /* The sprite's 1.7 stroke is drawn for 18px; at 14px it thins
     to a hairline, so it is thickened to keep the same weight. */
  stroke-width:2.1;
}

.gps-office__address{margin:0;font-style:normal}

.gps-office__link{
  color:inherit;
  text-decoration:none;
  /* Long email addresses are the thing that overflows a narrow
     card. Break them rather than let them escape it. */
  overflow-wrap:anywhere;
  transition:color var(--dur) var(--ease);
}
.gps-office__link:hover,
.gps-office__link:focus-visible{
  color:var(--gps-red);
  text-decoration:underline;
  text-underline-offset:.2em;
}

.gps-office__text{overflow-wrap:anywhere}

/* The hours row: a small label on the chip's line, the times
   under it in the row's own grey. */
.gps-office__hours-title{
  margin:0;
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
  letter-spacing:var(--tr-wide);
  line-height:1.875rem;
  text-transform:uppercase;
  color:var(--gps-black);
}
.gps-office__hours-body{margin:0}

/* Pushed to the bottom edge so cards of different heights still
   line their directions links up with each other. */
.gps-office__go{margin:auto 0 0;padding-block-start:var(--sp-2)}

.gps-office__directions{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  letter-spacing:var(--tr-wide);
  text-transform:uppercase;
  color:var(--gps-black);
  text-decoration:none;
  transition:color var(--dur) var(--ease);
}
.gps-office__directions:hover,
.gps-office__directions:focus-visible{color:var(--gps-red)}

.gps-office__arrow{
  width:1rem;
  height:1rem;
  flex:none;
  transition:transform var(--dur) var(--ease);
}
.gps-office__directions:hover .gps-office__arrow,
.gps-office__directions:focus-visible .gps-office__arrow{transform:translateX(.25rem)}

/* ---- Enquiry card ------------------------------------------
   The reference's form card: white, a soft shadow a little deeper
   than the offices', and a centred title. The standfirst under the
   title is ours; it is a Customizer string, and emptying it gives
   the reference's title-then-fields exactly. */
.gps-contact__enquiry{
  padding:clamp(var(--sp-5),2vw,1.5625rem);
  border-radius:var(--radius-tile);
  background:var(--gps-white);
  box-shadow:var(--gps-contact-shadow);
  outline:1px solid transparent;   /* the edge in forced-colors mode */
}

.gps-enquiry__title{
  margin:0 0 var(--sp-4);
  font-size:clamp(var(--fs-xl),1.8vw,1.625rem);
  font-weight:var(--fw-bold);
  letter-spacing:var(--tr-tight);
  line-height:1.2;
  text-align:center;
  color:var(--gps-black);
}

.gps-enquiry__intro{
  max-inline-size:40ch;
  margin:calc(var(--sp-2) * -1) auto var(--sp-5);
  font-size:var(--fs-sm);
  line-height:1.6;
  text-align:center;
  color:var(--grey-600);
  text-wrap:pretty;
}

/* The outcome banner. Colour is never the only signal: the good
   state is bordered on the left and the bad state is bordered and
   bold, so the difference survives a monochrome screen and the
   two most common forms of colour blindness. */
.gps-enquiry__note{
  margin:0 0 var(--sp-4);
  padding:var(--sp-3) var(--sp-4);
  border-inline-start:4px solid var(--gps-black);
  background:var(--grey-100);
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--gps-black);
}
.gps-enquiry__note--bad{
  border-inline-start-color:var(--gps-red);
  font-weight:var(--fw-bold);
}
/* The redirect lands on this banner (it takes the #enquiry id
   when there is one) and focuses it. The scroll margin keeps the
   card's title in view above it, and the offset keeps the outline
   off the banner's own edge. */
.gps-enquiry__note{scroll-margin-block-start:var(--sp-10)}
.gps-enquiry__note:focus-visible{outline-offset:2px}

.gps-enquiry__form{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--sp-3);
}

.gps-enquiry__field{position:relative;margin:0}

/* Out of sight but in the accessibility tree. The same geometry
   as .visually-hidden, restated rather than borrowed, because that
   class is !important and the invalid state below has to be able
   to bring the label back. */
.gps-enquiry__label{
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  overflow:hidden;
  clip:rect(0 0 0 0);
  white-space:nowrap;
  border:0;
}

.gps-enquiry__star{margin-inline-start:.15em}

.gps-enquiry__input{
  display:block;
  inline-size:100%;
  min-height:2.75rem;
  padding:.5rem .875rem;
  border:1px solid var(--gps-contact-line);
  border-radius:var(--radius-0);
  background:var(--gps-white);
  /* font:inherit and not a font stack: a bare <input> does not
     inherit the page's family or size. 17px also keeps iOS Safari
     from zooming the page when a field takes focus, which it does
     to anything under 16px. */
  font:inherit;
  font-size:var(--fs-base);
  line-height:1.5;
  color:var(--gps-black);
  transition:border-color var(--dur) var(--ease);
}
.gps-enquiry__input::placeholder{color:var(--grey-600);opacity:1}
.gps-enquiry__input:hover,
.gps-enquiry__input:focus{border-color:var(--gps-black)}

.gps-enquiry__textarea{
  min-height:6rem;
  /* Vertical only: a horizontal drag inside a grid track that is
     already minmax(0,…) can force the whole layout wider. */
  resize:vertical;
}

/* A field that failed: its label comes back, in red, above it --
   by now the field may be filled and its placeholder gone -- and
   the edge thickens to 2px without shifting the text inside. */
.gps-enquiry__field.is-invalid .gps-enquiry__label{
  position:static;
  width:auto;
  height:auto;
  margin:0 0 var(--sp-1);
  overflow:visible;
  clip:auto;
  white-space:normal;
  display:block;
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  color:var(--gps-red);
}
.gps-enquiry__field.is-invalid .gps-enquiry__input{
  border-color:var(--gps-red);
  box-shadow:inset 0 0 0 1px var(--gps-red);
}
/* That inset shadow outranks the site's focus ring, which is also a
   box-shadow, so the ring is put back here: without it a failed
   field -- the one a visitor is sent back to -- is the one field
   whose focus cannot be seen. */
.gps-enquiry__field.is-invalid .gps-enquiry__input:focus-visible{
  box-shadow:inset 0 0 0 1px var(--gps-red),0 0 0 6px var(--gps-black);
}

/* Once a field has something in it, its placeholder is gone and
   nothing on screen would name it. The label comes back, small, on
   the field's top edge, where it moves nothing. Browsers without
   :has() keep the hidden label and lose only this. */
.gps-enquiry__field:not(.is-invalid):has(> .gps-enquiry__input:not(:placeholder-shown)) .gps-enquiry__label{
  top:0;
  left:.5rem;
  width:auto;
  height:auto;
  margin:0;
  padding:0 .375rem;
  overflow:visible;
  clip:auto;
  transform:translateY(-50%);
  background:var(--gps-white);
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
  line-height:1.2;
  color:var(--grey-600);
}

/* The honeypot. Clipped rather than display:none -- some bots skip
   fields hidden the obvious way, and this one is meant to be filled
   in. It is already aria-hidden and tabindex="-1" in the markup, so
   nothing reaches it but a script reading the DOM.

   The child input is pinned to 1px as well: an unstyled <input>
   keeps its default ~177px width, and although the wrapper clips
   it, it still reports a box wider than the page to anything
   measuring layout. */
.gps-enquiry__pot{
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  border:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  white-space:nowrap;
}
.gps-enquiry__pot input{width:1px;height:1px;min-height:0;padding:0;border:0}

/* Left-aligned at its own width, as the reference's is. */
/* ---- CAPTCHA ------------------------------------------------
   At the foot of the form, as on the reference: a small grey
   heading, then the question -- the one label that stays in view,
   because it is the instruction -- then the answer box. */
.gps-enquiry__captcha{
  display:grid;
  gap:var(--sp-2);
  margin-block-start:var(--sp-2);
}
.gps-enquiry__captcha-head{
  margin:0;
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--grey-600);
}
.gps-enquiry__captcha-q{
  display:block;
  margin:0 0 var(--sp-2);
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  color:var(--gps-black);
}
.gps-enquiry__field--captcha.is-invalid .gps-enquiry__captcha-q{color:var(--gps-red)}
.gps-enquiry__captcha-input{max-inline-size:12rem}

.gps-enquiry__actions{margin:var(--sp-2) 0 0}

.gps-enquiry__required,
.gps-enquiry__consent{
  margin:0;
  font-size:var(--fs-xs);
  line-height:1.6;
  color:var(--grey-600);
}

/* Stacked on a tablet the card is the full width of the page, and
   one field per line would be a column of long thin boxes. Two
   per line there; the message, the button and the small print
   keep the full width. align-items:end keeps a row's two fields
   level when one of them has grown a label above it. */
@media (48rem <= width < 64rem){
  .gps-enquiry__form{
    grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:var(--sp-4);
    align-items:end;
  }
  .gps-enquiry__field--wide,
  .gps-enquiry__actions,
  .gps-enquiry__required,
  .gps-enquiry__consent{grid-column:1 / -1}
}

/* The no-form fallback: the contact details, when gps-core is not
   there to receive a submission. */
.gps-enquiry__direct{margin:0;padding:0;display:grid;gap:var(--sp-3)}
.gps-enquiry__direct .gps-office__link{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-3);
  color:var(--gps-black);
}
.gps-enquiry__direct .gps-office__link:is(:hover,:focus-visible){color:var(--gps-red)}
.gps-enquiry__direct .gps-office__ico{
  width:1.125rem;
  height:1.125rem;
  stroke-width:1.7;
  color:var(--gps-red);
}

/* ---- A form plugin's own markup ----------------------------
   When a shortcode is set in the Customizer, the provider's form
   replaces ours inside the same card. These rules give the common
   elements the built-in form's look without naming any one
   plugin's classes. Contact Form 7 ships almost unstyled and takes
   all of it; WPForms and Gravity Forms style their own forms with
   stronger selectors, and win, which is what their settings
   screens expect. */
.gps-enquiry__provider :is(p,ul,ol){margin:0 0 var(--sp-3)}
.gps-enquiry__provider label{
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  color:var(--gps-black);
}
.gps-enquiry__provider :is(input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=hidden],[type=file],[type=image],[type=range],[type=color]),select,textarea){
  display:block;
  inline-size:100%;
  max-inline-size:100%;
  min-height:2.75rem;
  margin-block-start:var(--sp-1);
  padding:.5rem .875rem;
  border:1px solid var(--gps-contact-line);
  border-radius:var(--radius-0);
  background:var(--gps-white);
  font:inherit;
  /* Contact Form 7 puts each field inside its <label>, which is
     bold above; the typed text should not be. */
  font-weight:var(--fw-reg);
  font-size:var(--fs-base);
  line-height:1.5;
  color:var(--gps-black);
}
.gps-enquiry__provider textarea{min-height:7.5rem;resize:vertical}
.gps-enquiry__provider :is(input,textarea)::placeholder{color:var(--grey-600);opacity:1}
/* The site's primary button, restated: a plugin's submit cannot be
   given the .btn classes. */
.gps-enquiry__provider :is(input[type=submit],button[type=submit]){
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-height:3.25rem;
  padding:var(--sp-3) var(--sp-7);
  border:3px solid var(--gps-yellow);
  border-radius:var(--radius-0);
  background:var(--gps-yellow);
  color:var(--gps-black);
  font-family:var(--font-head);
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  letter-spacing:var(--tr-wide);
  text-transform:uppercase;
  cursor:pointer;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease);
}
.gps-enquiry__provider :is(input[type=submit],button[type=submit]):hover{
  background:var(--gps-black);
  border-color:var(--gps-black);
  color:var(--gps-white);
}

/* ---- Print --------------------------------------------------
   A contact page is one of the few pages on a site that genuinely
   gets printed, and the two things worth carrying onto paper are
   the addresses and the phone numbers. The form cannot be posted
   from a sheet of paper and the map is a rectangle of ink. */
@media print{
  .gps-contact__map,
  .gps-contact__enquiry{display:none}
  /* On screen the map stands in for the title; on paper the map is
     gone, so the title comes back. !important because that is what
     .visually-hidden uses. */
  .gps-contact__title{
    position:static!important;
    width:auto;
    height:auto;
    margin:0 0 1rem;
    overflow:visible;
    clip:auto;
    white-space:normal;
  }
  .gps-contact__layout{display:block}
  .gps-offices{grid-template-columns:repeat(2,1fr)}
  .gps-office__body{box-shadow:none;border:1px solid #000}
  .gps-office__chip{background:none;color:#000}
}
