/* Site header — the site nav, overlaid on top of the page hero, pinned (sticky)
   and fading transparent → solid on scroll. Two headers share these rules: the
   template-part header (internal pages, a direct child of .wp-site-blocks) and
   the in-hero header inside the Slider hero pattern (home). Scoped to pages,
   case studies and the 404 (all of which open with a hero) so templates without
   a hero (blog/archives) keep the header in normal flow.
   The base overlay (.pad-hero .site-header, below) is what renders in the editor,
   where this fixed rule is out of scope. */
.wp-site-blocks {
  position: relative;
  /* Clip the horizontal overhang of full-bleed `.breakout` elements (they use
     100vw, which exceeds the content box by the scrollbar width). `clip` (not
     `hidden`) creates no scroll container, so it doesn't break the fixed header or
     any in-flow sticky positioning. */
  overflow-x: clip;
}

body:is(.page, .single-case_study, .error404) .site-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 10;
  background-color: transparent;
  transition:
    inset-block-start var(--transition-duration) ease,
    background-color var(--transition-duration) ease;
}

body.admin-bar:is(.page, .single-case_study, .error404) .site-header {
  inset-block-start: 32px;
}

body:is(.page, .single-case_study, .error404) .site-header.scrolling {
  background-color: var(--wp--preset--color--background);
  border-bottom: 1px solid var(--wp--preset--color--primary);
}

/* The header spans full width and uses the global gutter (root padding) for its
   inline padding, so the logo and nav line up with the hero heading beneath,
   which uses the same token. */
.site-header__inner {
  padding-block: var(--wp--preset--spacing--xs, 1.5rem);
  padding-inline: var(--wp--style--root--padding-left, 1.25rem);
}

.wp-block-site-logo.is-default-size img {
  width: clamp(12.5rem, 25.3vw, 30.25rem);
  height: auto;
}

/* ---- Mobile menu overlay ---------------------------------------------------
   Core's default overlay is a bare white panel with the links jammed into the
   top-left corner and the enquiry CTA bleeding off the edge. Restyle it as a
   full-screen navy panel (matching the hero + footer): links vertically centred
   on the site gutter, white and shifting to primary (light blue) on hover, a
   white close in the top-right, and the CTA given room to breathe.
   (The previous `.responsive-container .is-menu-open` descendant selector never
   matched — `.is-menu-open` sits on the container itself, not a descendant.) */
/* Selector mirrors core's default-overlay rule (which paints the panel white)
   with an extra `.site-header` to win the navy — otherwise core's higher
   specificity keeps the background white. */
.site-header
  .wp-block-navigation:not(.has-background)
  .wp-block-navigation__responsive-container.is-menu-open:not(
    .disable-default-overlay
  ) {
  /* A more generous inline gutter than the site root padding (only ~20px on
     mobile) so the menu breathes; shared with the close button below. */
  --menu-pad-inline: var(--wp--preset--spacing--s);
  background-color: var(--wp--preset--color--secondary);
  color: var(--wp--preset--color--white);
  padding-block: var(--wp--preset--spacing--l);
  padding-inline: var(--menu-pad-inline);
}

/* Vertically centre the menu within the full-height panel. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-close {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-block-size: 100%;
}

.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-container-content {
  width: 100%;
  padding-block-start: 0;
}

/* Menu list — generous vertical rhythm for a full-screen menu. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__container {
  gap: var(--wp--preset--spacing--s);
  width: 100%;
  align-items: flex-start;
}

/* Links: big, white, heading font, sliding to primary on hover/keyboard focus. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item__content:not(.button) {
  display: inline-block;
  font-family: var(--wp--preset--font-family--heading);
  font-size: var(--wp--preset--font-size--xtra-large);
  font-weight: var(--wp--custom--font-weight--medium, 500);
  line-height: 1.1;
  color: var(--wp--preset--color--white);
  transition:
    color var(--transition-duration) ease,
    transform var(--transition-duration) ease;
}

.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item__content:not(.button):hover,
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item__content:not(.button):focus-visible {
  color: var(--wp--preset--color--primary);
  transform: translateX(0.5rem);
}

/* Focus ring that reads on navy (replaces the browser's default box). Only shows
   for keyboard focus; a mouse click leaves no ring. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item__content:not(.button):focus-visible {
  outline: 2px solid var(--wp--preset--color--primary);
  outline-offset: 0.5rem;
  border-radius: 2px;
}

/* Enquiry CTA — full-width, clearly separated, and recoloured so it reads on the
   navy panel: a WHITE accent bar + white focus ring (the default navy ones are
   invisible here), and a hover that flips to a solid WHITE button with navy text
   instead of the default navy-on-navy (which would vanish). Chevron pushed to the
   trailing edge. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item:has(> .wp-block-navigation-item__content.button) {
  margin-block-start: var(--wp--preset--spacing--m);
}

.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation-item__content.button {
  --button-padding: 1.125rem 1.25rem;
  /* Core's overlay CSS zeroes padding on ALL nav-item content (to flush the plain
     links); that also hits the CTA, since it's a nav-item content with `.button`
     added. Re-declare it here (this selector out-specifies core's) so the button
     keeps its padding — setting only --button-padding above isn't enough, as the
     `.button` rule that consumes it is lower-specificity than core's reset. */
  padding: var(--button-padding);
  --button-accent: var(--wp--preset--color--white);
  /* --button-outline-color: var(--wp--preset--color--white);
  --button-hover-bg: var(--wp--preset--color--primary);
  --button-hover-color: var(--wp--preset--color--secondary);
  --button-hover-accent: var(--wp--preset--color--primary);
  --button-hover-icon-color: var(--wp--preset--color--secondary); */
}

/* Close (X): fixed to the top-right gutter, white, primary on hover. */
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-container-close {
  position: fixed;
  inset-block-start: var(--wp--preset--spacing--s);
  inset-inline-end: var(--menu-pad-inline, var(--wp--preset--spacing--s));
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  color: var(--wp--preset--color--white);
  transition: color var(--transition-duration) ease;
}

.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-container-close:hover,
.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-container-close:focus-visible {
  color: var(--wp--preset--color--primary);
}

.site-header
  .wp-block-navigation__responsive-container.is-menu-open
  .wp-block-navigation__responsive-container-close
  svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* Core navigation switches to desktop mode at 600px when `overlayMenu: mobile`
   is set. The header script toggles `.is-mobile-nav` between 600px and
   `--site-nav-desktop-breakpoint` to extend overlay mode to the chosen width. */
.site-header.is-mobile-nav
  .wp-block-navigation__responsive-container-open:not(.always-shown) {
  display: flex;
}

.site-header.is-mobile-nav
  .wp-block-navigation__responsive-container:not(.hidden-by-default):not(
    .is-menu-open
  ) {
  display: none;
}

.wp-block-navigation {
  .current-menu-item {
    color: var(--wp--preset--color--primary);
    font-weight: var(--wp--custom--font-weight--semi-bold, 600);
  }
}

@media (min-width: 782px) {
  .site-header .wp-block-navigation__container.cluster {
    --cluster-space: clamp(2.1875rem, 4.6vw, 4.375rem);
  }
}

/* Nav CTA bridge. The "Make An Enquiry" menu item is a core navigation link
   tagged with the shared `.button` class (render_block filter on the front end,
   editor filter in the canvas). Core's `.wp-block-navigation
   .wp-block-navigation-item__content` rules match with equal specificity but load
   after the theme CSS, so they win for `display` and `color` — restate just those
   two (default + hover) at higher specificity, reusing the button component's own
   custom properties so the primary variant still drives the values. Everything
   else (background, accent bar, radius, chevron) the component already wins. */
.wp-block-navigation .wp-block-navigation-item__content.button {
  display: inline-flex;
  color: var(--button-color);
}

.wp-block-navigation .wp-block-navigation-item__content.button:hover,
.wp-block-navigation .wp-block-navigation-item__content.button:focus-visible {
  color: var(--button-hover-color);
}

/* Section's own supports forbid an editable text colour (color.text is false
   in its block.json) — text colour is a fixed consequence of the background
   chosen, not independently editable. Any section on the navy background
   gets white text/links, footer included. (Button styles now live in the shared
   `.button` component — assets/css/buttons.css.) */
.wp-block-pad-section-block.has-secondary-background-color {
  color: var(--wp--preset--color--white);
}

.wp-block-pad-section-block.has-secondary-background-color a {
  color: inherit;
}

/* Footer / navy-section links inherit their context's colour (white nav links,
   the mid-grey credit line) and go primary on hover. */
.wp-block-pad-section-block.has-secondary-background-color a:hover,
.wp-block-pad-section-block.has-secondary-background-color a:focus-visible {
  color: var(--wp--preset--color--primary);
}

.footer-logo img {
  width: 220px;
  height: auto;
}

/* Footer ------------------------------------------------------------------
   The footer's two columns come from pad/columns-block, which for two children
   renders a Switcher — already a deterministic 2 -> 1 with no ragged middle
   step. What DID wrap raggedly was the content inside those columns, so the
   rules below give the nav and the address deterministic behaviour too.
   Container queries, not media queries: same explicit stepping, keyed to the
   component's own width.

   TWO named containers, because the two things being controlled answer to
   different widths:
     - `footer-columns` (the Switcher) — for "have the columns stacked yet?",
       which is a fact about the whole footer.
     - `footer-column`  (one column)   — for content inside a column, whose
       available space is the COLUMN, not the footer.
   Getting this wrong is silent: a query aimed at the wider ancestor simply
   never matches its threshold, and the rule looks like it does nothing. */
footer .wp-block-pad-columns-block {
  container: footer-columns / inline-size;
  row-gap: 3.625rem;
}

footer .wp-block-pad-column-block {
  container: footer-column / inline-size;
}

/* A step down from body copy — the footer is supporting information, and at
   18px the four nav items could not fit one phone-width line. */
footer {
  font-size: var(--wp--preset--font-size--small);
}

footer .wp-block-navigation {
  font-size: var(--wp--preset--font-size--small);
}

/* The address is one flowing block (the hard <br> it used to carry forced a
   break at a fixed point, so below that width the two halves wrapped
   independently and stranded the postcode on its own line). The measure is set
   so it breaks at the comma after "Business Centre" rather than mid-street-name,
   and `pretty` keeps a lone word off the last line. The postcode itself is held
   together by a non-breaking space in the markup (parts/footer.html). */
footer .footer-address {
  max-inline-size: 50ch;
  text-wrap: pretty;
}

/* Accreditation badges — a pad/logo-grid instance, reusing the same normalised
   logo treatment as the client logo wall rather than duplicating it. The badges
   used to be a single flat sprite PNG, which is why they could not be resized,
   respaced or reflowed onto two rows. The block's own `--stack-space:
   rhythm-large` gives the separation from the WG logo that QA asked for.
   `--grid-min` is set so auto-fit lands on 3 tracks in the footer column (two
   decks of three) and 2 once the footer stacks on a phone. */
footer .footer-accreditations {
  /* 10.5rem, not 11rem: both give the same three 193px tracks at desktop, but
     11rem needed 200px-per-track including the gap, which just missed 3-up at
     tablet widths and left ~116px of slack inside each of two tracks. */
  --grid-min: 10.5rem;
  --grid-gap: 1.5rem;
  --grid-row-gap: 1.5rem;

  /* Hard floor of TWO badges per row. auto-fit on its own dropped to a single
     column once the footer stacked — an 11rem track plus its gap needs ~200px,
     more than half a phone — leaving a six-deck-tall stack. Capping the track
     minimum at half the row (less half a gap) makes two columns the narrowest
     possible outcome, while --grid-min still drives the 3-up step on desktop.
     A floor, not a breakpoint: nothing to re-tune if the badge count changes. */
  --grid-columns: repeat(
    auto-fit,
    minmax(min(var(--grid-min), calc(50% - var(--grid-gap) / 2)), 1fr)
  );

  /* The column is `stack--align-end`, which would otherwise shrink the grid to
     its content width instead of letting it fill the column. */
  align-self: stretch;
}

/* Equal badge heights at EVERY width, without hard-coding one. The box is full
   track width with an aspect-ratio matching the WIDEST badge (Dulux Connect at
   3.5:1), so the box height is always track-width / 3.5. Every badge whose own
   ratio is <= 3.5 is therefore height-constrained under `object-fit: contain`
   and draws at exactly the box height — no badge is ever the odd short one.
   Revisit --accreditation-ratio if a wider badge is ever added to the set. */
/* Tracks are 1fr, so they're wider than the capped badge box and each badge has
   slack inside its own track. Pushing that slack to the trailing edge lines the
   right-hand column up with the WG logo above it — but only while the footer is
   in its two-column form. Once it stacks, the tracks get much wider than the
   badges (~116px of slack at tablet widths) and hugging the right reads as a
   mistake, so the slack goes to both sides instead. */
footer .footer-accreditations figure {
  display: flex;
  justify-content: flex-end;
}

@container footer-columns (width < 45rem) {
  footer .footer-accreditations figure {
    justify-content: flex-start;
  }

  /* The right-hand column carries `stack--align-end`, which right-aligns the WG
     logo so it sits over the badges and against the container edge. That only
     makes sense while the column IS on the right — once the footer stacks, the
     logo should share the left edge with the nav and address above it. The
     badge grid is unaffected: it sets `align-self: stretch`, so it keeps
     spanning the full width either way. */
  footer .wp-block-pad-column-block.stack--align-end {
    align-items: flex-start;
  }
}

footer .footer-accreditations img {
  inline-size: 100%;
  max-inline-size: 9.5rem;
  block-size: auto;
  aspect-ratio: var(--accreditation-ratio, 3.5);
  object-fit: contain;
}

/* Pin the footer nav's gap to a FIXED rhythm step. It otherwise inherits the
   fluid `spacing-m` preset (30px here, 36px on a phone), which spent 90px of a
   phone's width on gaps AND made the wrap threshold drift with the viewport —
   so the stacking rule below could not be aimed reliably. Fixed gap, fixed
   threshold, same result every time. */
footer .wp-block-navigation__container {
  gap: var(--wp--custom--rhythm--base, 1.625rem);
}

/* Stack the nav below the width where four items stop fitting one line. The
   labels alone measure 307px, so with the 26px gaps above a single line needs
   ~385px (24.1rem); 25rem is that plus a little headroom for a longer label.
   An explicit step, not intrinsic wrapping — the old behaviour dropped just
   "Contact" onto a second row, which is exactly the ragged wrap QA objects to.

   Keyed to `footer-column`, NOT `footer-columns`: the nav sits inside one
   column, so the width it has to fit into is the column's, not the footer's.
   Aimed at the footer this rule was dead in the range that mattered — while the
   columns are side by side the footer is ~770px (never below 25rem) but each
   column is only ~373px, so the nav wrapped and nothing fired. */
@container footer-column (width < 25rem) {
  footer .wp-block-navigation__container {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--wp--custom--rhythm--small, 0.9375rem);
  }
}

/* Speech-bubble shell: a thin-bordered box with a pointer tail at the
   bottom-right. Applied to a columns block, which supplies the two-column
   layout — this class only decorates (border, radius, padding, tail). The tail
   is `position:absolute` so it stays out of the columns' flex flow. */
.speech-bubble {
  --bubble-border: color-mix(
    in srgb,
    var(--wp--preset--color--primary) 70%,
    var(--wp--preset--color--white)
  );
  position: relative;
  border: 1px solid var(--bubble-border);
  padding: var(--wp--preset--spacing--m, 4rem);
}

/* Tail: an angular notch dropping from the bottom edge, near the right corner —
   an angled LEFT edge and a straight vertical RIGHT edge, so the tip sits at the
   bottom-right. Drawn as an inline-SVG background so those two edges continue the
   1px outline while the white fill masks the bubble's bottom border across the
   opening (the interior "opens" into the tail). Clip-path can't do this (it would
   clip the border too); the 1px top overlap lets the edges meet the border
   seamlessly.
   NOTE: an SVG used as a CSS background can't read custom properties, so the
   stroke colour is the resolved value of --bubble-border (primary 70% + white);
   keep the two in sync if that mix ever changes. */
.speech-bubble::after {
  content: "";
  position: absolute;
  inline-size: 53px;
  block-size: 29px;
  inset-block-start: calc(100% - 0px);
  inset-inline-end: 64px;
  background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 53 29'><polygon points='0,0,52,0,52,28' fill='%23ffffff'/><polyline points='0,0,52,28,52,0' fill='none' stroke='%23a1c6e6' stroke-width='1'/></svg>")
    center / 100% 100% no-repeat;
}

/* Gravity Forms enquiry form (the "Let's Talk" pattern). Scoped to the
   `.enq-form` column so it doesn't touch forms elsewhere. Fields are laid out
   as two columns — Name/Phone/Email stacked on the left, Message spanning the
   right — matching the design; GF already renders the field wrapper as a grid,
   so we just re-map the tracks and place the fields by their cssClass. */
/* GF ships its own high-specificity `.gform_wrapper.gravity-theme` grid
   (repeat(12,1fr)) that loads after the theme CSS, so re-mapping the tracks and
   placing fields needs !important — the standard way to re-theme GF layout. */
.enq-form .gform_fields {
  display: grid;
  grid-template-columns: 1fr 1fr !important;
  row-gap: 0.875rem !important;
  align-items: start;
}

.enq-form .gform_fields .enq-col-a {
  grid-column: 1 / 2 !important;
}

.enq-form .gform_fields .enq-col-b {
  grid-column: 2 / 3 !important;
  grid-row: 1 / span 3 !important;
  block-size: 100%;
}

.enq-form .enq-col-b .ginput_container_textarea,
.enq-form .enq-col-b textarea {
  block-size: 100%;
}

.enq-form .enq-col-b textarea {
  block-size: 10.8rem;
  resize: vertical;
}

/* Inputs: light-bordered boxes on white, matching the panel. */
.enq-form .gform_wrapper input[type="text"],
.enq-form .gform_wrapper input[type="email"],
.enq-form .gform_wrapper input[type="tel"],
.enq-form .gform_wrapper textarea {
  inline-size: 100%;
  box-sizing: border-box;
  border: 1px solid var(--wp--preset--color--primary) !important;
  border-radius: 0px !important;
  box-shadow: none !important;
  font-size: var(--wp--preset--font-size--medium, 1.2rem) !important;
  font-weight: var(--wp--custom--font-weight--light, 300) !important;
  color: var(--wp--preset--color--secondary) !important;
}

/* Inputs: light-bordered boxes on white, matching the panel. */

.enq-form .gform_wrapper input[type="text"],
.enq-form .gform_wrapper input[type="email"],
.enq-form .gform_wrapper input[type="tel"] {
  height: 3rem !important;
}

/* Submit button: the tertiary CTA treatment (navy fill, white label, light-blue
   left bar). It's an <input>, so it can't carry `data-button-variant` — this
   duplicates the tertiary variant's palette from buttons.css by hand. Keep the
   two in sync if that variant changes. The chevron is a (white) background image
   rather than an inline icon, and stays white on both rest and hover. */
.enq-form .gform_wrapper .gform_footer input[type="submit"],
.enq-form .gform_wrapper .gform_footer .gform_button {
  padding: 0.9rem 3rem 0.9rem 1.5rem !important;
  border: 0 !important;
  border-left: 4px solid var(--wp--preset--color--primary) !important;
  border-radius: 0 !important;
  background-color: var(--wp--preset--color--secondary) !important;
  background-image: url(../images/icons/chevron-white.svg) !important;
  background-repeat: no-repeat !important;
  background-position: right 1.25rem center !important;
  background-size: 0.7em auto !important;
  color: var(--wp--preset--color--white) !important;
  font-weight: var(--wp--custom--font-weight--bold, 700);
  cursor: pointer;
  transition:
    background-color var(--transition-duration, 380ms) ease,
    border-color var(--transition-duration, 380ms) ease;
  font-size: var(--wp--preset--font-size--medium, 1.2rem) !important;
  font-weight: var(--wp--custom--font-weight--bold, 700) !important;
}

.gform-theme--foundation .gform_footer,
.gform-theme--foundation .gform_page_footer {
  margin-block-start: var(--wp--preset--spacing--s, 1.5rem) !important;
}

.enq-form .gform_wrapper .gform_footer input[type="submit"]:hover,
.enq-form .gform_wrapper .gform_footer .gform_button:hover {
  /* Hover: light-blue fill; the left bar flips to navy so it stays visible once
     the background is blue — mirroring the tertiary variant's hover. */
  background-color: var(--wp--preset--color--primary) !important;
  border-left-color: var(--wp--preset--color--secondary) !important;
}

/* Below the bubble's stacking point, drop the form to a single column. */
@media (max-width: 600px) {
  .enq-form .gform_fields {
    grid-template-columns: 1fr !important;
  }

  .enq-form .gform_fields .enq-col-a,
  .enq-form .gform_fields .enq-col-b {
    grid-column: 1 / -1 !important;
    grid-row: auto !important;
  }
}

/* Brand logo variant of the image block (accreditation/feature columns): keep
   the logo at its natural proportions, left-aligned, instead of filling the
   column width like a content photo. The logo sits in a FIXED-height band so
   every column's heading starts at the same offset — aligning logos and
   headings across columns in flexbox (the Switcher) without needing subgrid.
   Where the layout is a Grid + `.grid--rows` (4+ columns) subgrid aligns them
   too; this band keeps the two routes visually identical. */
.wp-block-pad-image-block.is-logo {
  block-size: 4rem;
  text-align: start;
}

.wp-block-pad-image-block.is-logo img {
  inline-size: auto;
  max-inline-size: 100%;
  block-size: auto;
  max-block-size: 100%;
  object-fit: contain;
  object-position: left top;
}

/* ---- Home hero (slider + in-pattern header) ---------------------------------
   The home hero carries its OWN header (site-logo + navigation, a <header
   class="site-header">) inside the hero pattern, so it displays in the editor
   alongside the hero (unlike the template-part header, which the page editor
   never renders). front-page.html therefore omits the header template part.
   On the front end the shared `body.page .site-header` rules above pin it and
   fade it to solid on scroll — identical to the template-part header. This base
   rule overlays it on the hero in the EDITOR, where that fixed rule is out of
   scope (the canvas body isn't `.page`). */
.pad-hero {
  position: relative;
}

.pad-hero .site-header {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 10;
  column-gap: 1rem;
}

/* White top gradient over each slide. */
.wp-block-pad-cover-slide-block::after {
  content: "";
  position: absolute;
  inset-block-start: -5px;
  inset-inline: 0;
  block-size: 65%;
  inline-size: 100%;
  background: linear-gradient(
    to bottom,
    rgb(255 255 255 / 100%) 0%,
    rgb(255 255 255 / 0%) 65%
  );
  z-index: 3;
  pointer-events: none;
}

.wp-block-pad-cover-slide-block::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 100%;
  inline-size: 100%;
  background-color: var(--wp--preset--color--secondary);
  opacity: 0.4;
  z-index: 2;
  pointer-events: none;
}

/* Internal page hero — a shorter STATIC cover (a standalone pad/cover-slide, no
   pad/cover parent = no Swiper), sharing .pad-hero (overlaid + sticky header) but
   with its own shorter height and its own gradient export. */
.pad-hero--page {
  --pad-cover-min-height: 545px;

  .wp-block-pad-cover-slide-block.cover > .cover__center {
    margin-block-end: var(--wp--preset--spacing--m, 4rem);
  }
}

/* Internal pages hero gradient */
.pad-hero--page .wp-block-pad-cover-slide-block::after {
  block-size: 100%;
  background: linear-gradient(
    to bottom,
    rgb(255 255 255 / 100%) 0%,
    rgb(255 255 255 / 0%) 65%,
    rgb(255 255 255 / 0%) 65%
  );
}

/* Internal hero overlay: a full-height/width SECONDARY (navy) tint at 80% opacity
   over the image (instead of the block's bottom-only legibility gradient). The
   white SVG gradient (::after, z-index 3) sits over the top of it; the content
   (z-index 3) stays legible on the tint. */
.pad-hero--page .wp-block-pad-cover-slide-block::before {
  opacity: 0.8;
}

/* Slider navigation — the square arrow buttons shared by the slider blocks (the
   case-studies carousel and the image slider). Dark navy square, white chevron,
   primary on hover. Hidden until the block's view.js marks it `.is-ready` (the
   arrows do nothing without JS). */
.slider-nav {
  display: flex;
  gap: 0.375rem;
}

.slider-nav:not(.is-ready) {
  display: none;
}

.slider-nav button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.95rem;
  block-size: 2.95rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--wp--preset--color--secondary);
  color: var(--wp--preset--color--white);
  cursor: pointer;
  transition: background-color var(--transition-duration, 380ms) ease;
}

.slider-nav button:hover,
.slider-nav button:focus-visible {
  background: var(--wp--preset--color--primary);
}

.slider-nav button svg {
  inline-size: 0.75rem;
  block-size: 0.9375rem;
}

/* Works-list + image-slider layout (external-works pattern). A 2-column grid —
   text/list beside the image — with the slider's arrows/button in a SECOND row, in
   the image's column, so the image bottom lines up exactly with the list and the
   controls sit in their own reserved track underneath (no overflow). Built on the
   `.grid` primitive (added via the block's className alongside this) so it reflows
   2→1 column query-free; --grid-min is sized so at most two columns form at the
   content width. The slider is `display:contents` (its style.scss) so its image and
   footer become the 2nd and 3rd grid items — the footer pins to the last column
   (grid-column:-1/-2). */
/* Single case study: a switcher holding the case gallery ALWAYS floats the
   gallery above the text once the columns stack — structurally, so it can't be
   forgotten per instance. Same mechanism as `.switcher--reverse` (wrap-reverse
   flips only the stacked line order; the desktop row order is untouched, gallery
   stays right). The pattern file carries `switcher--reverse` too (redundant but
   harmless); existing case studies in the DB predate that class, which is why
   this is enforced here rather than migrated post-by-post. Assumes the gallery
   column is LAST in the DOM (it is, everywhere) — a gallery-left layout would
   need the `order` approach (`.switcher--media-left`) instead. */
/* .switcher:has(> .wp-block-pad-column-block > .wp-block-pad-case-gallery) {
  flex-wrap: wrap-reverse;
} */

/* External-works: text/list beside the image slider, which dissolves into this
   grid (display:contents) so its Swiper + arrows/button footer become grid items.
   Two things auto-fit alone can't give: the image ABOVE the text when the grid
   stacks, and TWO different vertical gaps (26px text↔image, but 0.375rem
   image↔arrows). Solved without restyling the grid across a breakpoint:
   - The grid's row-gap is the base Stack rhythm (26px) — right for text↔image.
   - The arrows/button footer is pulled to a tight 0.375rem under the image with a
     static negative margin that holds in BOTH layouts (arrows belong to the
     image, not the content flow), so no per-state gap change is needed.
   - column-gap is fixed (not the fluid `l`) so auto-fit's 2→1 collapse point is
     deterministic (< 56rem + 6rem = 62rem grid width), letting the container
     query below match it exactly. The query only reorders CHILD grid items — a
     container can't restyle itself, but its descendants query it fine. */
.works-grid {
  container-type: inline-size;
  --grid-min: 28rem;
  column-gap: 6rem;
  row-gap: var(--wp--custom--rhythm--base, 1.625rem);
  align-items: stretch;
}

.works-grid .pad-image-slider__footer {
  margin-block-start: calc(
    0.375rem - var(--wp--custom--rhythm--base, 1.625rem)
  );
}

/* Stacked (grid narrower than the 2-column collapse point): float the image and
   its arrows above the text so the media leads on mobile. Text stays last, a full
   base-rhythm gap below the arrows. */
@container (max-width: 62rem) {
  .works-grid .pad-image-slider__swiper,
  .works-grid .pad-image-slider__footer {
    order: -1;
  }
}

/* Reverse toggle (Container → "Reverse layout"): put the image on the LEFT and the
   text on the right, with the arrows/button following the image into the first
   column. Uses `order` + a first-column pin so it stays query-free — no explicit
   `grid-column: 2` (which would spawn a phantom column in the 1-column mobile
   stack). `grid-auto-flow: dense` lets the text backfill the empty top-right cell
   (otherwise the footer's fixed column pushes it down into row 2). */
.works-grid.is-reversed {
  grid-auto-flow: dense;
}

.works-grid.is-reversed .pad-image-slider__swiper,
.works-grid.is-reversed .pad-image-slider__footer {
  order: -1;
}

.works-grid.is-reversed .pad-image-slider__footer {
  grid-column: 1 / 2;
}

/* Editor preview: the slider is a single block there (not display:contents), so
   just move the whole slider ahead of the text block. */
.works-grid.is-reversed > .wp-block-pad-image-slider {
  order: -1;
}

/* Media card — a linked image with a bottom-up scrim overlay that reveals a title
   (+ optional meta line) on hover / keyboard focus. Shared by the case-studies
   carousel cards (pad/case-card) and the case-studies grid (pad/case-study-card).
   `.frame` (primitives.css) on `.media-card__media` locks the image ratio. */
.media-card {
  --frame-ratio: 4 / 2;

  position: relative;
  display: block;
  overflow: hidden;
  text-decoration: none;
  color: var(--wp--preset--color--white);
  background: var(--wp--preset--color--secondary);
}

.media-card__media {
  display: block; /* .frame needs a block box for aspect-ratio to take effect. */
}

.media-card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.15em;
  padding: var(--wp--preset--spacing--xs, 1.5rem);
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--wp--preset--color--black) 88%, transparent),
    color-mix(in srgb, var(--wp--preset--color--black) 12%, transparent) 55%,
    transparent 80%
  );
  opacity: 0;
  transition: opacity var(--transition-duration, 380ms) ease;
}

.media-card:hover .media-card__overlay,
.media-card:focus-visible .media-card__overlay,
.media-card:focus-within .media-card__overlay {
  opacity: 1;
}

/* Touch devices can't hover — keep the overlay (title + meta) permanently shown. */
@media (hover: none) {
  .media-card__overlay {
    opacity: 1;
  }

  .media-card__title {
    transform: none;
  }
}

.media-card__title {
  color: var(--wp--preset--color--white);
  font-weight: var(--wp--custom--font-weight--bold, 700);
  font-size: var(--wp--preset--font-size--medium, 1.2rem);
  line-height: 1.15;
  transform: translateY(0.6rem);
  transition: transform var(--transition-duration, 380ms) ease;
}

.media-card:hover .media-card__title,
.media-card:focus-within .media-card__title {
  transform: translateY(0);
}

.media-card__meta {
  color: color-mix(in srgb, var(--wp--preset--color--white) 80%, transparent);
  font-size: var(--wp--preset--font-size--small, 0.95rem);
}

@media (prefers-reduced-motion: reduce) {
  .media-card__overlay,
  .media-card__title {
    transition: none;
  }
}
