/* ==========================================================================
   India Bungy theme styles

   Built from html/, the Bootstrap edition of the design, which follows the
   Figma Make source: Tailwind spacing and breakpoints (sm 640, md 768,
   lg 1024, xl 1280). Class names are html's. Layout comes from the custom
   Bootstrap CSS build loaded before this file (assets/vendor/bootstrap/);
   this file holds colour, type, size, effects and state.

   Deliberate differences from html: nav links are slightly tighter from 1280
   to 1439 so the menu fits, and the mobile menu keeps the theme's rows of a
   link plus a chevron button.

   No build step on the server: edit this file, save, refresh.

   Contents
     1. Reset
     2. Design tokens
     3. Base
     4. Header: bar, top bar, menu, dropdowns, WhatsApp, mobile menu
     5. Footer: grid, logo, social, link columns, bar, floating chat
     6. Home: hero, with its stats
     7. Buttons
     8. Home: marquee
     9. Home: about split
    10. Home: products, with the shared eyebrow, h2 and outline button
    11. Home: impact
    12. Home: gallery
    13. Home: testimonials
    14. Home: clients
    15. Home: contact
    16. Shared: section links and scroll reveals
    17. Content placeholder
    18. WooCommerce: shop and product category
    19. WooCommerce: single product
    20. Shared: inner pages, the page hero and page.php body
    21. Page: Our Factory
    22. Page: Gallery, the justified photo grid and the photo viewer
    23. Page: Clients, the region rail and the client directory
    24. Page: Contact Us, the action cards, office list, quote card and map
    25. Page: Blog, the post cards, their meta line and the pager
    26. Page: Blog single, the post hero, image, body and previous / next row
    27. Page: 404, the outlined code, message and requested address
   ========================================================================== */

/* 1. Reset =============================================================== */

/* Bootstrap's reboot loads first. These are the theme's own defaults on top
   of it: images, icons and video as blocks, bare buttons, cleared margins. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote {
  margin-block: 0;
}

ul,
ol {
  margin-block: 0;
}

strong,
b {
  font-weight: 700;
}

/* 2. Design tokens ======================================================= */

:root {
  /* Colours, straight from the design's theme.css. --ib-primary and
	   --ib-dark are overwritten by the Customizer. */
  --ib-primary: #ff3d00;
  --ib-primary-hover: #ff6b1a;
  --ib-dark: #111111;

  /* The footer is two shades darker than the top bar in the design, not the
	   same colour. Kept as its own token so the Customizer's dark colour still
	   drives the top bar without flattening the two together. */
  --ib-footer-bg: #0d0d0d;

  --ib-bg: #f2f1ef;
  --ib-surface: #ffffff;
  --ib-text: #111111;
  /* One step darker than the page ground: the clients strip and the history
     band on /our-factory/ sit on it. */
  --ib-secondary: #e8e7e5;
  --ib-muted: #dedddb;
  --ib-muted-text: #5a5a5a;
  --ib-border: rgba(0, 0, 0, 0.09);

  /* Typography. */
  --ib-font-body: "Barlow", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ib-font-head: "Barlow Condensed", "Barlow", system-ui, sans-serif;
  --ib-font-mono: "DM Mono", ui-monospace, "Consolas", monospace;

  /* Rhythm. */
  --ib-container: 1400px;
  --ib-topbar-height: 32px;
  --ib-navbar-height: 64px;

  /* Easing for the entrance animations, matching the static build. */
  --ib-ease-out: cubic-bezier(0, 0, 0.58, 1);
}

/* 3. Base ================================================================ */

/* No faux bold or italic. The published Figma site sets this, so a weight with
   no font file draws the nearest real face instead of a smeared fake: DM Mono
   at 600/700 shows the real 500. Without it tags, eyebrows and labels come out
   heavier than the design. */
:root {
  font-synthesis: none;
}

body {
  background-color: var(--ib-bg);
  color: var(--ib-text);
  font-family: var(--ib-font-body);
  font-size: 16px;
  font-weight: 400;
  /* 1.5, the design's base.
	 *
	 * It applies only where the design used an arbitrary font size, because
	 * those inherit: the 13px nav links land on 19.5px and the 11px top bar on
	 * 16.5px, both confirmed against the Figma file. Where the design used a
	 * named Tailwind size instead, that size ships its own leading and the rule
	 * below it spells the pixel value out: text-xs is 12/16 and text-sm is
	 * 14/20, never 1.5. */
  line-height: 1.5;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--ib-font-head);
  font-weight: 800;
  line-height: 1.05;
  text-transform: uppercase;
}

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  color: var(--ib-primary);
}

.ib-icon {
  flex: none;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The shared page box. Same width and same side padding as the footer, so a
   heading in the content lines up with the footer headings beneath it. The
   design uses these two values throughout: 24px on a phone, 56px above. */
.ib-container {
  max-width: var(--ib-container);
  margin-inline: auto;
  padding-inline: 24px;
}

@media (min-width: 1024px) {
  .ib-container {
    padding-inline: 56px;
  }
}

.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.ib-skip-link:focus {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 1100;
  width: auto;
  height: auto;
  clip: auto;
  padding: 10px 16px;
  background: var(--ib-primary);
  color: #fff;
  font-weight: 600;
}

/* 4. Header ============================================================== */

/* Ported from the NAV block of html/style.css, with its class names. Which
   part shows at which width, flex alignment and spacing come from Bootstrap
   classes in header.php; this block holds colour, type, size and state.

   Two things differ from html on purpose:
   - between 1280 and 1439 nav links are tighter (10px padding, 0.05em
     tracking), because html's 14px does not fit nine items beside the logo
     and the WhatsApp button until 1440;
   - the mobile menu splits a row with a sub-list into the link and a separate
     chevron button, one list open at a time (main.js). */

.ib-nav {
  position: relative;
  z-index: 1030;
  width: 100%;
  background: var(--ib-surface);
  border-bottom: 1px solid var(--ib-border);
  transition:
    background-color 0.3s,
    box-shadow 0.3s;
}

.ib-sticky-header .ib-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

/* Logged in, WordPress pushes the page down by its admin bar (32px, 46px up
   to 782) but a fixed header stays at the top, behind the bar, and leaves the
   same gap above the page. Below 601 the bar scrolls away with the page, so
   the header keeps to the top there. WordPress only, html/ has no admin bar. */
.admin-bar.ib-sticky-header .ib-nav {
  top: 32px;
}

@media (max-width: 782px) {
  .admin-bar.ib-sticky-header .ib-nav {
    top: 46px;
  }
}

@media (max-width: 600px) {
  .admin-bar.ib-sticky-header .ib-nav {
    top: 0;
  }
}

/* Past 40px of scroll main.js adds .is-scrolled: translucent, blurred, with
   Tailwind's shadow-sm. */
.ib-nav.is-scrolled {
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow:
    0 1px 3px 0 rgba(0, 0, 0, 0.1),
    0 1px 2px -1px rgba(0, 0, 0, 0.1);
}

/* Anything wider than the screen is clipped here rather than on body.
 *
 * Plugin widgets, the testimonial slider above all, render thousands of pixels
 * wide. Clipping that on body works on a desktop but not on a phone, where the
 * page stays pannable sideways; and once the page pans, the fixed header stays
 * anchored to the document and slides out of view, leaving an empty white bar.
 * Clipping inside this wrapper keeps the document exactly as wide as the
 * screen, and leaves the header, which sits outside it, alone.
 */
.ib-content {
  overflow-x: hidden; /* Fallback for older browsers. */
  overflow-x: clip; /* Clips without turning this into a scroll container. */
}

/* Push the page down only when the header is lifted out of the flow: its bars
   plus its 1px bottom border, 65px and 97px as html has them. */
.ib-sticky-header .ib-content {
  padding-top: calc(var(--ib-navbar-height) + 1px);
}

@media (min-width: 1024px) {
  .ib-sticky-header.ib-has-topbar .ib-content {
    padding-top: calc(var(--ib-navbar-height) + var(--ib-topbar-height) + 1px);
  }
}

/* Top bar: full width, hard against the screen edges, shown from 1024. */
.ib-topbar {
  height: var(--ib-topbar-height);
  background: var(--ib-dark);
  color: #fff;
  font-family: var(--ib-font-mono);
  font-size: 11px;
}

.ib-topbar__group {
  opacity: 0.7;
}

.ib-topbar a,
.ib-topbar .ib-topbar__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #fff;
  transition: opacity 0.15s;
}

.ib-topbar a:hover {
  color: #fff;
  opacity: 1;
}

/* Logo and menu row, in the 1400px box. */
.ib-nav__row {
  height: var(--ib-navbar-height);
}

.ib-nav__logo {
  display: inline-flex;
  align-items: center;
  flex: none;
}

/* Height comes from the Customizer as --ib-logo-height. Width follows the
   image's own proportions. max-width leaves room for the 24px side padding and
   the 38px menu button, so the logo only narrows once it truly cannot fit
   (html's 264px logo stays full size down to 350px).

   Two classes on purpose: WooCommerce ships `.woocommerce-page img
   { height: auto; max-width: 100% }`, which loads after this file and would
   otherwise blow the logo up to full size on shop and product pages. */
.ib-nav .ib-nav__logo img {
  height: var(--ib-logo-height, 40px);
  width: auto;
  max-width: calc(100vw - 86px);
  object-fit: contain;
}

.ib-logo-text {
  display: inline-flex;
  align-items: center;
  font-family: var(--ib-font-head);
  font-size: 20px;
  font-weight: 900;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.ib-nav__item {
  position: relative;
}

/* The source asks for weight 600, but the published site never loads Barlow
   Condensed 600, so browsers draw the 700 face. 700 matches what it shows.

   Spacing is html's (14px, 0.07em) from 1440. Between 1280 and 1439 that
   needs 69px more than the row has, so it steps down to 10px, 0.05em. */
.ib-nav__link {
  padding: 8px 10px;
  color: rgba(17, 17, 17, 0.6);
  font-family: var(--ib-font-head);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.15s;
}

@media (min-width: 1440px) {
  .ib-nav__link {
    padding-inline: 14px;
    letter-spacing: 0.07em;
  }
}

.ib-nav__link:hover {
  color: var(--ib-text);
}

.ib-nav__item.is-open > .ib-nav__link {
  color: var(--ib-primary);
}

/* The design paints the current menu item in the brand colour, hovered or
   not (html/style.css; the walker adds .is-current). */
.ib-nav__link.is-current,
.ib-mobile__top.is-current {
  color: var(--ib-primary);
}

.ib-nav__link .ib-caret {
  transition: transform 0.15s;
}

.ib-nav__item.is-open .ib-caret {
  transform: rotate(180deg);
  color: var(--ib-primary);
}

.ib-nav__placeholder {
  font-size: 13px;
  color: var(--ib-muted-text);
}

/* Dropdowns. main.js opens them (.is-open) on hover with a 180ms close delay,
   on keyboard focus, and on first tap on a touch screen. Without the script
   they still open on hover and focus. */
.ib-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 50;
  min-width: 220px;
  background: var(--ib-surface);
  border-top: 2px solid var(--ib-primary);
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition:
    opacity 0.15s,
    transform 0.15s;
}

.ib-nav__item.is-open > .ib-dropdown,
html:not(.ib-js) .ib-nav__item:hover > .ib-dropdown,
html:not(.ib-js) .ib-nav__item:focus-within > .ib-dropdown {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.ib-dropdown a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  border-bottom: 1px solid var(--ib-border);
  color: rgba(17, 17, 17, 0.7);
  font-family: var(--ib-font-body);
  font-size: 14px;
  line-height: 20px; /* text-sm */
  transition:
    color 0.15s,
    background-color 0.15s;
}

.ib-dropdown a:last-child {
  border-bottom: 0;
}

.ib-dropdown a:hover {
  background: var(--ib-muted);
  color: var(--ib-primary);
}

.ib-dropdown a .ib-icon {
  opacity: 0;
  color: var(--ib-primary);
  transition: opacity 0.15s;
}

.ib-dropdown a:hover .ib-icon {
  opacity: 1;
}

/* WhatsApp button, shown from 1024. */
.ib-nav__wa {
  padding: 10px 20px;
  background: var(--ib-primary);
  color: #fff;
  font-family: var(--ib-font-head);
  font-size: 12px;
  font-weight: 700;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background-color 0.15s;
}

.ib-nav__wa:hover {
  background: var(--ib-primary-hover);
  color: #fff;
}

.ib-nav__burger {
  color: var(--ib-text);
}

.ib-nav__burger .ib-icon--close {
  display: none;
}

.ib-nav__burger[aria-expanded="true"] .ib-icon--open {
  display: none;
}

.ib-nav__burger[aria-expanded="true"] .ib-icon--close {
  display: block;
}

/* Mobile panel, below 1280. */
.ib-mobile {
  max-height: 80vh;
  overflow-y: auto;
  background: var(--ib-surface);
  border-top: 1px solid var(--ib-border);
}

.ib-mobile__group {
  border-bottom: 1px solid rgba(0, 0, 0, 0.045); /* border/50 in the design */
}

.ib-mobile__top {
  padding: 16px 24px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 14px;
  font-weight: 700;
  line-height: 20px; /* text-sm */
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* The theme's own control, not in html: the chevron beside the name. */
.ib-mobile__toggle {
  flex: none;
  width: 52px;
  padding: 0;
  border-left: 1px solid var(--ib-border);
  color: var(--ib-muted-text);
}

.ib-mobile__toggle .ib-icon {
  transition: transform 0.15s;
}

.ib-mobile__toggle[aria-expanded="true"] {
  color: var(--ib-primary);
}

.ib-mobile__toggle[aria-expanded="true"] .ib-icon {
  transform: rotate(180deg);
}

.ib-mobile__sub {
  padding-bottom: 8px;
  background: rgba(222, 221, 219, 0.4);
}

.ib-mobile__sub a {
  display: block;
  padding: 10px 32px;
  color: var(--ib-muted-text);
  font-size: 14px;
  line-height: 20px; /* text-sm */
  transition: color 0.15s;
}

.ib-mobile__sub a:hover {
  color: var(--ib-primary);
}

/* 5. Footer ============================================================== */

/* Ported from the FOOTER block of html/style.css, with its class names. The
   grid, column spans, padding and the bar's row layout are Bootstrap classes
   in footer.php; this block holds colour, type, size and state. */

.ib-footer {
  background: var(--ib-footer-bg);
  color: #fff;
}

/* Bootstrap's .grid with html's column counts: one column, two from 768,
   four from 1024 with the brand spanning two. */
.ib-footer__top {
  --bs-gap: 2.5rem;
  --bs-columns: 1;
}

@media (min-width: 768px) {
  .ib-footer__top {
    --bs-columns: 2;
  }
}

@media (min-width: 1024px) {
  .ib-footer__top {
    --bs-columns: 4;
  }
}

/* html has a bare image here; the theme links it home. A block exactly as wide
   as the logo keeps the 20px gap below it free of inline line-box space. */
.ib-footer__logo {
  display: block;
  width: max-content;
  max-width: 100%;
  margin-bottom: 20px;
}

/* Two classes beat WooCommerce's `.woocommerce-page img`, as in the header.
   Capped at the column width only, like html's image. */
.ib-footer .ib-footer__logo img {
  height: var(--ib-logo-height, 40px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* The site logo is dark red on transparent, which vanishes against the dark
   footer. Flattening it to white keeps it readable. Switched off in the
   Customizer, or skipped entirely when a separate footer logo is uploaded. */
.ib-logo-img-invert {
  filter: brightness(0) invert(1);
  opacity: 0.8;
}

.ib-footer .ib-logo-text {
  color: #fff;
}

.ib-footer__about {
  max-width: 320px;
  margin: 0 0 24px;
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
  font-weight: 300;
  line-height: 1.625;
}

.ib-footer__social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.4);
  transition:
    color 0.2s,
    border-color 0.2s;
}

.ib-footer__social a:hover {
  border-color: var(--ib-primary);
  color: var(--ib-primary);
}

/* An h2 for the page outline, styled as html's h5. */
.ib-footer__title {
  margin: 0 0 20px;
  color: #fff;
  font-family: var(--ib-font-head);
  font-size: 12px;
  font-weight: 700;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.ib-footer__links {
  gap: 10px;
}

.ib-footer__links a {
  color: rgba(255, 255, 255, 0.4);
  font-size: 12px;
  font-weight: 300;
  line-height: 16px; /* text-xs */
  transition: color 0.15s;
}

.ib-footer__links a:hover {
  color: var(--ib-primary);
}

/* The border sits on the 1400px box, not edge to edge. */
.ib-footer__bar .container {
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.ib-footer__copyright,
.ib-footer__credit {
  color: rgba(255, 255, 255, 0.25);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px; /* text-xs */
}

.ib-footer__credit {
  transition: color 0.15s;
}

.ib-footer__credit:hover {
  color: var(--ib-primary);
}

/* Floating chat button, bottom right on every page. WhatsApp brand green from
   the design, not the site accent, because the colour is how people spot it. */
.ib-wa-float {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 1040;
  width: 56px;
  height: 56px;
  background: #25d366;
  color: #fff;
  box-shadow:
    0 20px 25px -5px rgba(0, 0, 0, 0.3),
    0 8px 10px -6px rgba(0, 0, 0, 0.3);
  transition: transform 0.15s;
}

.ib-wa-float:hover {
  color: #fff;
  transform: scale(1.1);
}

/* 6. Home: hero ========================================================== */

/* Ported from the HERO block of html/style.css, with its class names. Layout
   (flex column, container, padding, margins, the stats corner and which width
   shows them) is Bootstrap classes in hero.php.

   The header is fixed and overlays the top of the hero, exactly as html has
   it, so the front page drops the padding the other templates need. */
.ib-sticky-header.ib-hero-top .ib-content {
  padding-top: 0;
}

@media (min-width: 1024px) {
  .ib-sticky-header.ib-hero-top.ib-has-topbar .ib-content {
    padding-top: 0;
  }
}

.ib-hero {
  height: 100vh;
  min-height: 640px;
  background: #000;
}

/* max-width is reset because the Reset section caps every video at 100%,
   which this one must ignore to cover a viewport wider than the file. */
.ib-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  opacity: 0.5;
}

.ib-hero__veil--v {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    #000 0%,
    rgba(0, 0, 0, 0.4) 50%,
    transparent 100%
  );
}

.ib-hero__veil--h {
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, rgba(0, 0, 0, 0.6), transparent);
}

.ib-hero__bar {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  background: var(--ib-primary);
}

.ib-hero__body {
  z-index: 10;
}

.ib-hero__rule {
  width: 40px;
  height: 1px;
  background: var(--ib-primary);
}

.ib-hero__kicker span {
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.25em;
  text-transform: uppercase;
}

/* Overrides the global h1-h6 rule, which is 800 at 1.05. */
.ib-hero__title {
  color: #fff;
  font-family: var(--ib-font-head);
  font-size: clamp(4rem, 13vw, 10rem);
  font-weight: 900;
  line-height: 0.88;
  letter-spacing: -0.01em;
}

.ib-outline {
  -webkit-text-stroke: 2px var(--ib-primary);
  color: transparent;
}

.ib-hero__lede {
  max-width: 576px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 16px;
  font-weight: 300;
  line-height: 1.625;
}

@media (min-width: 1024px) {
  .ib-hero__lede {
    font-size: 18px;
  }
}

/* Stats, bottom right from 1024. */
.ib-hero__stat {
  width: 144px;
  height: 96px;
  background: rgba(0, 0, 0, 0.7);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-left: 1px solid rgba(255, 255, 255, 0.1);
}

.ib-hero__stat b {
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-size: 24px;
  font-weight: 900;
  line-height: 1;
}

.ib-hero__stat span {
  margin-top: 4px;
  color: rgba(255, 255, 255, 0.5);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Entrance, with the same delays html uses. */
@keyframes ib-rise {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes ib-rise-lg {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes ib-rise-sm {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes ib-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.ib-hero__kicker {
  animation: ib-rise 0.7s var(--ib-ease-out) 0.1s both;
}

.ib-hero__title {
  animation: ib-rise-lg 0.8s var(--ib-ease-out) 0.2s both;
}

.ib-hero__lede {
  animation: ib-rise-sm 0.7s var(--ib-ease-out) 0.4s both;
}

.ib-hero__cta {
  animation: ib-rise-sm 0.6s var(--ib-ease-out) 0.55s both;
}

.ib-hero__stats {
  animation: ib-fade 0.8s var(--ib-ease-out) 0.8s both;
}

/* 7. Buttons ============================================================= */

/* html's shared buttons. --outline sits with the products section. */
.ib-btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 16px 32px;
  font-family: var(--ib-font-head);
  font-size: 14px;
  font-weight: 700;
  line-height: 20px; /* text-sm */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: all 0.2s;
}

.ib-btn--solid {
  background: var(--ib-primary);
  color: #fff;
}

.ib-btn--solid:hover {
  background: var(--ib-primary-hover);
  color: #fff;
}

.ib-btn--ghost {
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
}

.ib-btn--ghost:hover {
  border-color: var(--ib-primary);
  color: var(--ib-primary);
}

.ib-btn .ib-icon--arrow {
  transition: transform 0.2s;
}

.ib-btn:hover .ib-icon--arrow {
  transform: translateX(4px);
}

/* Lucide Play with fill-current, as html: filled, and it keeps its 2px
   stroke. */
.ib-icon--fill {
  fill: currentColor;
}

/* 8. Home: marquee ======================================================= */

/* Ported from the MARQUEE block of html/style.css, with its class names. The
   track holds the list three times over, and the keyframe slides it exactly
   one copy, so the loop is seamless. Change the item count freely; the third
   is what the -33.333% depends on, not the number of labels. */
.ib-marquee {
  background: var(--ib-primary);
  overflow: hidden;
  padding-block: 14px;
  user-select: none;
}

.ib-marquee__track {
  display: flex;
  width: max-content;
  white-space: nowrap;
  animation: ib-marquee 22s linear infinite;
}

@keyframes ib-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-33.333%);
  }
}

.ib-marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 20px;
  padding-inline: 20px;
  font-family: var(--ib-font-head);
  font-size: 14px;
  font-weight: 900;
  line-height: 20px; /* text-sm */
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: #fff;
}

.ib-marquee__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
}

/* 9. Home: about split =================================================== */

/* Ported from the SPLIT and ABOUT blocks of html/style.css, with its class
   names. Layout (grid, spans, flex column, padding, the badges row) is
   Bootstrap classes in about.php.

   .ib-split is Bootstrap's .grid with no gap: one column, two from 1024. The
   contact section further down reuses it. */
.ib-split {
  --bs-gap: 0;
  --bs-columns: 1;
  min-height: 600px;
}

@media (min-width: 1024px) {
  .ib-split {
    --bs-columns: 2;
  }
}

.ib-about__media {
  background: var(--ib-dark);
  min-height: 400px;
}

.ib-about__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  opacity: 0.6;
}

/* Fades the photograph into the dark column beside it. */
.ib-about__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, transparent, rgba(17, 17, 17, 0.8));
}

.ib-about__year {
  position: absolute;
  bottom: 24px;
  left: 24px;
  z-index: 1;
  color: rgba(255, 255, 255, 0.1);
  font-family: var(--ib-font-head);
  font-size: clamp(5rem, 15vw, 10rem);
  font-weight: 900;
  line-height: 1;
  user-select: none;
}

.ib-about__tag {
  position: absolute;
  top: 32px;
  left: 32px;
  z-index: 1;
}

.ib-about__tag i {
  width: 4px;
  height: 48px;
  background: var(--ib-primary);
}

.ib-about__tag span {
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.ib-about__text {
  background: var(--ib-dark);
  color: #fff;
}

.ib-about__text h2 {
  margin: 0 0 24px;
  font-family: var(--ib-font-head);
  font-size: clamp(2.5rem, 5vw, 4rem);
  font-weight: 900;
  line-height: 0.92;
  text-transform: uppercase;
}

.ib-about__text h2 em {
  font-style: normal;
  color: var(--ib-primary);
}

.ib-about__text p {
  margin: 0 0 24px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 16px;
  font-weight: 300;
  line-height: 1.625;
}

.ib-about__text p:last-of-type {
  margin-bottom: 32px;
}

.ib-about__text strong {
  color: #fff;
  font-weight: 600;
}

/* Bootstrap's .grid: three badges, 16px apart. */
.ib-about__badges {
  --bs-gap: 1rem;
  --bs-columns: 3;
}

.ib-about__badge {
  padding: 16px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.ib-about__badge b {
  display: block;
  margin-bottom: 4px;
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-size: 20px;
  font-weight: 900;
  line-height: 28px; /* text-xl */
}

/* A block, as in html: its line is 10px x 1.5 = 15px instead of the 24px
   strut an inline span gets from its 16px parent. */
.ib-about__badge span {
  display: block;
  color: rgba(255, 255, 255, 0.4);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* The arrow slides out from the words on hover, so the gap is what animates.
   Scoped to .ib-about__text because .ib-link-more, further down this file,
   would otherwise win with its own 8px gap. */
.ib-about__text .ib-about__link {
  gap: 12px;
  color: var(--ib-primary);
  transition: gap 0.2s;
}

.ib-about__text .ib-about__link:hover {
  gap: 20px;
  color: var(--ib-primary);
}

/* 10. Home: products ===================================================== */

/* Ported from the shared text pieces and the PRODUCTS block of html/style.css,
   with its class names. Layout (container, section padding, the head row,
   grid, card spans, margins) is Bootstrap classes in products.php. */

.ib-section--light {
  background: var(--ib-bg);
}

/* Shared text pieces, used by several sections. */
.ib-eyebrow {
  display: block;
  margin-bottom: 12px;
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* "Trusted By" and "Get In Touch" carry no font-medium in the design. */
.ib-eyebrow--regular {
  font-weight: 400;
}

.ib-h2 {
  margin: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: clamp(2.5rem, 5vw, 4rem);
  font-weight: 900;
  line-height: 0.9;
  text-transform: uppercase;
}

/* A smaller section heading, for a secondary section such as the single
   product's related products. */
.ib-h2--sm {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  line-height: 1;
}

.ib-products__head .ib-h2 {
  font-size: clamp(2.8rem, 6vw, 5rem);
}

.ib-filters {
  gap: 1px;
}

.ib-filter {
  padding: 10px 20px;
  background: var(--ib-muted);
  color: var(--ib-muted-text);
  font-family: var(--ib-font-head);
  font-size: 12px;
  font-weight: 700;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: all 0.2s;
}

.ib-filter:hover {
  background: #e8e7e5; /* secondary */
  color: var(--ib-text);
}

.ib-filter.is-active {
  background: var(--ib-primary);
  color: #fff;
}

/* Bootstrap's .grid with html's column counts: one, two from 640, four from
   1024, 12px apart. */
.ib-grid-products {
  --bs-gap: 0.75rem;
  --bs-columns: 1;
}

@media (min-width: 640px) {
  .ib-grid-products {
    --bs-columns: 2;
  }
}

@media (min-width: 1024px) {
  .ib-grid-products {
    --bs-columns: 4;
  }
}

/* display lives here, not in a d-block class: a utility's !important would
   beat the filter's [hidden] and cards would never hide. */
.ib-card {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--ib-dark);
}

.ib-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.7;
  transition:
    opacity 0.5s,
    transform 0.5s;
}

.ib-card:hover img {
  opacity: 0.9;
  transform: scale(1.05);
}

.ib-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(0, 0, 0, 0.2) 50%,
    transparent 100%
  );
}

/* The background colour is set per category in products.php. */
.ib-card__tag {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  padding: 4px 8px;
  color: #fff;
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-card__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  padding: 20px;
}

.ib-card__foot h3 {
  margin: 0;
  color: #fff;
  font-family: var(--ib-font-head);
  font-size: 20px;
  font-weight: 900;
  line-height: 1.25;
  text-transform: uppercase;
  transition: color 0.15s;
}

.ib-card:hover .ib-card__foot h3 {
  color: var(--ib-primary);
}

.ib-card__more {
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 0.3s,
    transform 0.3s;
}

.ib-card:hover .ib-card__more {
  opacity: 1;
  transform: none;
}

.ib-btn--outline {
  padding: 16px 40px;
  border: 2px solid var(--ib-dark);
  color: var(--ib-dark);
  letter-spacing: 0.1em;
}

.ib-btn--outline:hover {
  background: var(--ib-dark);
  color: #fff;
}

/* 11. Home: impact ======================================================= */

/* Ported from the IMPACT block of html/style.css, with its class names.
   Layout (section padding, container, grid, cell flex column and padding) is
   Bootstrap classes in impact.php. */

.ib-impact {
  background: var(--ib-text);
}

.ib-impact__ghost {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: rgba(255, 255, 255, 0.03);
  font-family: var(--ib-font-head);
  font-size: 20vw;
  font-weight: 900;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

/* Bootstrap's .grid: two columns, four from 1024, 1px apart. The faint grid
   background shows through the gaps as the dividing lines. */
.ib-impact__grid {
  --bs-gap: 1px;
  --bs-columns: 2;
  z-index: 10;
  background: rgba(255, 255, 255, 0.05);
}

@media (min-width: 1024px) {
  .ib-impact__grid {
    --bs-columns: 4;
  }
}

.ib-impact__cell {
  background: var(--ib-text);
}

.ib-impact__num {
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-size: clamp(3rem, 7vw, 5.5rem);
  font-weight: 900;
  line-height: 1;
}

.ib-impact__label {
  color: rgba(255, 255, 255, 0.4);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* 12. Home: gallery ====================================================== */

/* Ported from the GALLERY block of html/style.css. The section, container and
   head row are Bootstrap classes in gallery.php; the mosaic uses row spans,
   which Bootstrap has no class for, so it stays here. */

.ib-gallery__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 8px;
  height: 480px;
}

@media (min-width: 1024px) {
  .ib-gallery__grid {
    height: 540px;
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(2, 1fr);
  }
}

.ib-gallery__item {
  position: relative;
  overflow: hidden;
  background: var(--ib-muted);
}

.ib-gallery__item:nth-child(1) {
  grid-column: span 2;
  grid-row: span 2;
}

.ib-gallery__item:nth-child(4) {
  grid-column: span 2;
}

/* The theme's seventh tile, not in html: it fills the last gap in both
   layouts (row four on phones, row two from 1024). */
.ib-gallery__item:nth-child(7) {
  grid-column: span 2;
}

.ib-gallery__item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.8;
  transition:
    opacity 0.5s,
    transform 0.5s;
}

.ib-gallery__item:hover img {
  opacity: 1;
  transform: scale(1.05);
}

.ib-gallery__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 61, 0, 0);
  transition: background-color 0.3s;
}

.ib-gallery__item:hover::after {
  background: rgba(255, 61, 0, 0.2);
}

/* 13. Home: testimonials ================================================= */

/* Ported from the TESTIMONIALS block of html/style.css, with its class names.
   Layout (section padding, container, centring, the heading row, margins) is
   Bootstrap classes in testimonials.php. */

.ib-testi {
  background: var(--ib-text);
}

.ib-testi__ghost {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  user-select: none;
  overflow: hidden;
  font-family: var(--ib-font-head);
  font-weight: 900;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.03);
  font-size: 18vw;
}

/* Narrower than the page box. Loads after Bootstrap, so it beats .container's
   own max-width. */
.ib-testi__shell {
  z-index: 10;
  max-width: 900px;
}

.ib-testi__rule i {
  width: 48px;
  height: 1px;
  background: var(--ib-primary);
}

.ib-testi__rule span {
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px; /* text-xs */
  letter-spacing: 0.25em;
  text-transform: uppercase;
}

/* The slider below is the Testimonial plugin's shortcode markup, restyled to
   match .ib-testi__slide and .ib-testi__dot in html/style.css. A few values
   need !important because the plugin prints its colours, border and bottom
   margin in an inline style keyed to the shortcode's #id. */

.ib-testi .sp-testimonial-free-wrapper {
  overflow: visible;
}

.ib-testi .sp-testimonial-free-wrapper .sp-testimonial-free-section {
  margin-bottom: 0 !important;
}

/* Fade instead of slide. The free plugin only slides, so the slides are
   stacked in one grid cell and Swiper's sideways movement (an inline transform
   on the wrapper) is cancelled. Swiper still marks the current slide, runs
   autoplay and drives the dots; the active slide fades in and lifts 16px, the
   same 0.5s as .ib-testi__slide. The stack is as tall as the longest quote,
   and never shorter than 180px, so the dots do not jump. */
.ib-testi .sp-testimonial-free-section .swiper-wrapper {
  display: grid;
  align-items: stretch;
  transform: none !important;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-item {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100% !important;
  height: auto;
  min-height: 180px;
  margin: 0 !important;
  text-align: center;
  opacity: 0;
  transform: translateY(16px);
  pointer-events: none;
  transition:
    opacity 0.5s,
    transform 0.5s;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-item.swiper-slide-active,
.ib-testi .sp-testimonial-free-section:not(.swiper-initialized) .sp-testimonial-item:first-child {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-free {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: transparent;
  border: 0 !important;
}

/* Quote, as .ib-testi__slide blockquote. */
.ib-testi .sp-testimonial-free-section .sp-testimonial-client-testimonial,
.ib-testi .sp-testimonial-free-section .sp-testimonial-client-testimonial p {
  margin: 0;
  padding: 0;
  color: var(--ib-surface) !important;
  font-family: var(--ib-font-head);
  font-size: clamp(1.6rem, 4vw, 2.8rem);
  font-style: normal;
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: normal;
  text-transform: uppercase;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-client-testimonial {
  margin-bottom: 24px;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-client-testimonial p::before {
  content: "\201C";
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-client-testimonial p::after {
  content: "\201D";
}

/* Name, as .ib-testi__slide cite. */
.ib-testi .sp-testimonial-free-section .sp-testimonial-client-name {
  margin: 0;
  padding: 0;
  color: var(--ib-primary) !important;
  font-family: var(--ib-font-mono);
  font-size: 12px;
  font-style: normal;
  font-weight: 700;
  line-height: 16px; /* text-xs, as html's cite */
  letter-spacing: 0.25em;
  text-transform: uppercase;
}

.ib-testi .sp-testimonial-free-section .sp-testimonial-client-name::before {
  content: "\2014\00a0";
}

/* Dots, as .ib-testi__dots and .ib-testi__dot. */
.ib-testi .sp-testimonial-free-section .testimonial-pagination {
  position: static;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin: 64px 0 0;
  transform: none;
}

.ib-testi .sp-testimonial-free-section .testimonial-pagination .swiper-pagination-bullet {
  width: 6px;
  height: 6px;
  margin: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2) !important;
  opacity: 1;
  transition: all 0.3s;
}

.ib-testi .sp-testimonial-free-section .testimonial-pagination .swiper-pagination-bullet:hover {
  background: rgba(255, 255, 255, 0.4) !important;
}

.ib-testi .sp-testimonial-free-section .testimonial-pagination .swiper-pagination-bullet-active,
.ib-testi .sp-testimonial-free-section .testimonial-pagination .swiper-pagination-bullet-active:hover {
  width: 40px;
  border-radius: 0;
  background: var(--ib-primary) !important;
}

/* 14. Home: clients ====================================================== */

/* Ported from the CLIENTS block of html/style.css, with its class names.
   Layout (section padding, container, head row, region rows, chip rows,
   margins and gaps) is Bootstrap classes in clients.php. */

.ib-clients {
  border-block: 1px solid var(--ib-border);
  background: var(--ib-secondary);
}

.ib-clients__region span {
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.ib-clients__region i {
  flex: 1;
  height: 1px;
  background: var(--ib-border);
}

.ib-chip {
  padding: 8px 16px;
  border: 1px solid var(--ib-border);
  background: var(--ib-surface);
  color: rgba(17, 17, 17, 0.7);
  font-size: 14px;
  font-weight: 600; /* font-medium is 600 in the design's theme.css */
  line-height: 20px; /* text-sm */
  cursor: default;
  transition:
    border-color 0.15s,
    color 0.15s;
}

.ib-chip:hover {
  border-color: var(--ib-primary);
  color: var(--ib-text);
}

/* 15. Home: contact ====================================================== */

/* Ported from the CONTACT block of html/style.css, with its class names.
   Layout (the split's columns and padding, the detail rows, the form's flex
   column and the field pair's grid) is Bootstrap classes in contact.php and
   the Contact Form 7 filters in inc/template-tags.php. The two-column split is
   .ib-split from the about section. */

.ib-contact__left {
  background: var(--ib-dark);
  color: #fff;
}

.ib-contact__right {
  background: var(--ib-surface);
}

.ib-contact__left h2 {
  margin: 0 0 24px;
  font-family: var(--ib-font-head);
  font-size: clamp(2.5rem, 5vw, 4rem);
  font-weight: 900;
  line-height: 0.92;
  text-transform: uppercase;
}

.ib-contact__left h2 em {
  font-style: normal;
  color: var(--ib-primary);
}

.ib-contact__left > p {
  margin: 0 0 40px;
  color: rgba(255, 255, 255, 0.5);
  font-weight: 300;
  line-height: 1.625;
}

.ib-contact__icon {
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: var(--ib-primary);
  transition: all 0.2s;
}

a.ib-contact__row:hover .ib-contact__icon {
  border-color: var(--ib-primary);
  background: rgba(255, 61, 0, 0.1);
}

.ib-contact__k {
  display: block;
  margin-bottom: 2px;
  color: rgba(255, 255, 255, 0.3);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-contact__v {
  display: block;
  color: #fff;
  font-size: 14px;
  font-weight: 600; /* font-medium */
  line-height: 20px; /* text-sm */
  transition: color 0.15s;
}

a.ib-contact__row:hover .ib-contact__v {
  color: var(--ib-primary);
}

.ib-contact__wa {
  letter-spacing: 0.1em;
}

.ib-form__title {
  margin: 0 0 32px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 24px;
  font-weight: 900;
  line-height: 32px; /* text-2xl */
  text-transform: uppercase;
}

/* Bootstrap's .grid: one column, two from 640, 16px apart. */
.ib-form__pair {
  --bs-gap: 1rem;
  --bs-columns: 1;
}

@media (min-width: 640px) {
  .ib-form__pair {
    --bs-columns: 2;
  }
}

/* The design's base layer gives every label weight 600. DM Mono ships 400 and
   500 only, so the real 500 face is drawn. */
.ib-form label {
  display: block;
  margin-bottom: 6px;
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-form input,
.ib-form select,
.ib-form textarea {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--ib-border);
  border-radius: 0;
  background: var(--ib-muted);
  color: var(--ib-text);
  font-family: var(--ib-font-body);
  font-size: 14px;
  line-height: 20px; /* text-sm */
  transition: border-color 0.15s;
}

.ib-form input::placeholder,
.ib-form textarea::placeholder {
  color: rgba(90, 90, 90, 0.4);
}

.ib-form input:focus,
.ib-form select:focus,
.ib-form textarea:focus {
  outline: none;
  border-color: var(--ib-primary);
}

/* Block, not the inline-block default. Otherwise the line box leaves a 6px
   gap under the textarea and the field comes out 6px taller than the design. */
.ib-form textarea {
  display: block;
  resize: none;
}

.ib-form__submit {
  gap: 8px;
  padding: 16px;
  background: var(--ib-primary);
  color: #fff;
}

.ib-form__submit:hover {
  background: var(--ib-primary-hover);
}

/* Contact Form 7 parts. The plugin wraps each field in an inline span, adds a
   spinner after the button and a message box under the form. None of them is
   in html, so they are kept out of the way of the design. */
.ib-form {
  position: relative;
}

.ib-form .wpcf7-form-control-wrap {
  display: block;
}

.ib-form .wpcf7-not-valid {
  border-color: #dc3232;
}

.ib-form .wpcf7-not-valid-tip {
  margin-top: 4px;
  font-size: 12px;
}

/* Sits inside the button while the form sends, instead of adding a row. */
.ib-form .wpcf7-spinner {
  position: absolute;
  right: 16px;
  bottom: 14px;
  margin: 0;
}

.wpcf7 .ib-form .wpcf7-response-output {
  margin: 0;
  padding: 12px 16px;
  border-width: 1px;
  font-size: 14px;
}

/* 16. Shared: section links and scroll reveals =========================== */

.ib-link-more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--ib-font-head);
  font-size: 14px;
  font-weight: 700;
  line-height: 20px; /* text-sm */
  text-transform: uppercase;
  letter-spacing: 0.1em;
  transition: color 0.15s ease;
}

/* Section links start muted and turn orange on hover. The colour is a modifier
   class, not an inline style, so the hover can win. */
.ib-link-more--dim {
  color: rgba(17, 17, 17, 0.5); /* text-foreground/50 */
}

.ib-link-more--muted {
  color: var(--ib-muted-text); /* text-muted-foreground */
}

.ib-link-more:hover {
  color: var(--ib-primary);
}

/* main.js adds .is-in as each block scrolls into view.
 *
 * Every rule is gated on .ib-js, which a one-line script in the head adds
 * before the page paints. Without it the content is simply visible, so a
 * blocked or broken script can never leave the page blank. */
.ib-js .ib-reveal {
  opacity: 0;
  transition:
    opacity 0.5s var(--ib-ease-out),
    transform 0.5s var(--ib-ease-out);
}

.ib-js .ib-reveal--x {
  transform: translateX(30px);
  transition-duration: 0.7s;
}

.ib-js .ib-reveal--y {
  transform: translateY(20px);
}

.ib-js .ib-reveal--scale {
  transform: scale(0.97);
}

.ib-js .ib-reveal.is-in {
  opacity: 1;
  transform: none;
}

/* 17. Content placeholder ================================================ */

/* Temporary, until the page templates are built. */

.ib-main {
  padding-block: 48px;
}

.ib-page-title,
.ib-entry-title {
  margin-bottom: 16px;
  font-size: 2rem;
}

.ib-entry {
  max-width: 72ch;
  margin-bottom: 48px;
}

.ib-entry-content p {
  margin-block: 0 1em;
}

/* 18. WooCommerce: shop and product category ============================ */

/* woocommerce/archive-product.php (shop, product categories and tags) follows
   html/our-products.html: the compact hero (20), the page ground, the home
   products grid and cards (10) and the blog pager (25). This block holds its
   toolbar, the category description and the empty state. WooCommerce's own
   stylesheets are not loaded (inc/woocommerce.php). */

/* A category or tag description, which WooCommerce prints as .term-description
   above the toolbar. The design has none; it reads as the section's lede. */
.term-description {
  max-width: 60ch;
  margin: 0 0 40px;
  color: var(--ib-muted-text);
  font-weight: 300;
  line-height: 1.625;
}

.term-description p {
  margin: 0 0 1em;
}

.term-description p:last-child {
  margin-bottom: 0;
}

/* The toolbar of html/our-products.html (Figma node 286:129), in the markup
   WooCommerce prints: the result count and the sort field. */
.ib-cat-toolbar {
  margin-bottom: 28px;
}

.ib-cat-toolbar .woocommerce-result-count {
  margin: 0;
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 11px;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* The sort field: 44px tall on the muted ground, its own 12px caret drawn as
   a mask so it takes the text colour. Full width on a phone; 214px wide (or
   as wide as its longest option) once the toolbar is a row. */
.ib-cat-toolbar .woocommerce-ordering {
  position: relative;
  margin: 0;
}

.ib-cat-toolbar .woocommerce-ordering::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 16px;
  width: 12px;
  height: 12px;
  margin-top: -6px;
  background: var(--ib-text);
  pointer-events: none;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}

.ib-cat-toolbar .orderby {
  display: block;
  width: 100%;
  height: 44px;
  padding: 0 40px 0 16px;
  background: var(--ib-muted);
  border: 1px solid var(--ib-border);
  border-radius: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-body);
  font-size: 14px;
  line-height: 20px;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: border-color 0.15s;
}

.ib-cat-toolbar .orderby:focus {
  outline: none;
  border-color: var(--ib-primary);
}

@media (min-width: 640px) {
  .ib-cat-toolbar .orderby {
    width: auto;
    min-width: 214px;
  }
}

/* An archive with no products: a muted line where the grid would be. */
.ib-cat-empty {
  padding-block: 40px;
  color: var(--ib-muted-text);
}

/* 19. WooCommerce: single product ======================================== */

/* woocommerce/single-product.php and its parts follow html/product-single.html
   (Figma node 298:2): the compact hero (20), the page ground, the photos
   (template-parts/product/gallery.php), the summary, the tabs, and the
   related products (single-product/related.php) in the home products grid
   and cards (10) on the secondary ground. WooCommerce's own stylesheets and
   gallery scripts are not loaded (inc/woocommerce.php). */

.ib-section--secondary {
  background: var(--ib-secondary);
}

/* Two equal columns from 1024px, 64px apart; stacked below. */
@media (min-width: 1024px) {
  .ib-pgallery,
  .ib-product-top > .summary {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* Photos: the main photo filling a white 4:3 box with a hairline (a photo
   with a transparent ground shows white), an orange zoom button in its
   corner, and a thumbnail strip that scrolls sideways on a 4px bar. */
.ib-pgallery {
  min-width: 0;
}

.ib-pgallery__main {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  cursor: zoom-in;
  background: #fff;
  border: 1px solid var(--ib-border);
}

.ib-pgallery__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ib-pgallery__zoom {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  background: var(--ib-primary);
  color: #fff;
  transition: background-color 0.2s;
}

.ib-pgallery__zoom:hover,
.ib-pgallery__zoom:focus-visible {
  background: var(--ib-primary-hover);
}

.ib-pgallery__thumbs {
  overflow-x: auto;
  padding-bottom: 2px;
}

.ib-pgallery__thumbs::-webkit-scrollbar {
  height: 4px;
}

.ib-pgallery__thumbs::-webkit-scrollbar-track {
  background: var(--ib-muted);
}

.ib-pgallery__thumbs::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.28);
}

@supports not selector(::-webkit-scrollbar) {
  .ib-pgallery__thumbs {
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.28) var(--ib-muted);
  }
}

.ib-pgallery__thumb {
  flex: 0 0 88px;
  width: 88px;
  height: 88px;
  padding: 0;
  overflow: hidden;
  background: var(--ib-text);
  border: 1px solid var(--ib-border);
}

.ib-pgallery__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.6;
  transition: opacity 0.2s;
}

.ib-pgallery__thumb:hover img,
.ib-pgallery__thumb.is-current img {
  opacity: 1;
}

.ib-pgallery__thumb.is-current {
  border-color: var(--ib-primary);
}

@media (min-width: 640px) {
  .ib-pgallery__thumb {
    flex-basis: 116px;
    width: 116px;
    height: 116px;
  }
}

/* Summary: the name with its orange rule, the short description, the
   category chips and the two enquiry buttons. */
.ib-product-title {
  margin: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 2.25rem;
  font-weight: 900;
  line-height: 0.96;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.ib-product-title::after {
  content: "";
  display: block;
  width: 64px;
  height: 4px;
  margin: 20px 0 26px;
  background: var(--ib-primary);
}

@media (min-width: 1024px) {
  .ib-product-title {
    font-size: 2.75rem;
  }
}

.woocommerce-product-details__short-description {
  color: var(--ib-muted-text);
  font-size: 16px;
  font-weight: 300;
  line-height: 26px;
}

.woocommerce-product-details__short-description p {
  margin: 0 0 12px;
}

.woocommerce-product-details__short-description > :last-child {
  margin-bottom: 0;
}

.woocommerce-product-details__short-description ul,
.ib-product-body ul {
  padding: 0 0 0 32px;
  list-style: none;
}

.woocommerce-product-details__short-description ul {
  margin: 0;
}

.woocommerce-product-details__short-description li,
.ib-product-body ul > li {
  position: relative;
}

.woocommerce-product-details__short-description li::before,
.ib-product-body ul > li::before {
  content: "\2022";
  position: absolute;
  left: -20px;
}

.ib-product-meta {
  margin-top: 32px;
  padding-top: 22px;
  border-top: 1px solid var(--ib-border);
}

.ib-product-meta__row {
  gap: 8px 10px;
}

.ib-product-meta__row + .ib-product-meta__row {
  margin-top: 12px;
}

.ib-product-meta__label {
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.625;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-product-meta__chip {
  padding: 7px 12px;
  background: #fff;
  border: 1px solid var(--ib-border);
  color: var(--ib-text);
  font-family: var(--ib-font-mono);
  font-size: 11px;
  line-height: 1.625;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition:
    border-color 0.15s,
    color 0.15s;
}

.ib-product-meta__chip:hover {
  border-color: var(--ib-primary);
  color: var(--ib-primary);
}

.ib-product-cta {
  margin-top: 28px;
}

@media (max-width: 639.98px) {
  .ib-product-cta .ib-btn {
    flex: 1 1 auto;
    justify-content: center;
  }
}

.ib-btn--line {
  border: 1px solid var(--ib-text);
  color: var(--ib-text);
}

.ib-btn--line:hover {
  background: var(--ib-text);
  color: #fff;
}

/* Tabs: one orange block per tab on a hairline, then the panel. */
.ib-tabs__nav {
  border-bottom: 1px solid var(--ib-border);
}

.ib-tabs__tab {
  padding: 10px 20px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition:
    color 0.15s,
    background-color 0.15s;
}

.ib-tabs__tab:hover {
  color: var(--ib-primary);
}

.ib-tabs__nav .active .ib-tabs__tab {
  background: var(--ib-primary);
  color: #fff;
}

.ib-tabs__panel {
  padding-top: 32px;
}

/* The product's own content, cleaned of its legacy WPBakery markup
   (ib_clean_legacy_shortcodes(), inc/woocommerce.php): plain text styles
   only, whatever made it. */
.ib-product-body {
  color: var(--ib-muted-text);
  font-size: 16px;
  font-weight: 300;
  line-height: 1.85;
  overflow-wrap: break-word;
}

.ib-product-body > :first-child {
  margin-top: 0;
}

.ib-product-body > :last-child {
  margin-bottom: 0;
}

.ib-product-body h2 {
  margin: 0 0 26px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 1.9rem;
  font-weight: 900;
  line-height: 1.04;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.ib-product-body h3 {
  margin: 70px 0 20px;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--ib-primary);
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 1.6rem;
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

@media (min-width: 1024px) {
  .ib-product-body h2 {
    font-size: 2.4rem;
  }
}

.ib-product-body p,
.ib-product-body ul,
.ib-product-body ol {
  margin: 0 0 22px;
}

.ib-product-body ol {
  padding-left: 32px;
}

.ib-product-body strong,
.ib-product-body b {
  color: var(--ib-text);
  font-weight: 600;
}

.ib-product-body a {
  color: var(--ib-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.15s;
}

.ib-product-body a:hover {
  color: var(--ib-primary-hover);
}

.ib-product-body img {
  height: auto;
}

.ib-product-body iframe {
  max-width: 100%;
}

/* Additional information tab: WooCommerce's attributes table. Not in the
   design; kept plain for a product that is given attributes. */
.ib-product-body .shop_attributes {
  width: 100%;
  border-collapse: collapse;
}

.ib-product-body .shop_attributes th,
.ib-product-body .shop_attributes td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--ib-border);
  text-align: left;
  vertical-align: top;
}

.ib-product-body .shop_attributes th {
  width: 30%;
  color: var(--ib-text);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-product-body .shop_attributes td p {
  margin: 0;
}

/* 20. Shared: inner pages ================================================ */

/* What every page other than the home page shares: the hero that opens it and,
   for a page with no template of its own (page.php), the editor content under
   it. The hero rules were first written for Our Factory and moved here
   unchanged when page.php began using them.

   Built from the --ib-* tokens only. The one rule that has to win over a home
   hero rule of equal weight is doubled up (.ib-hero.ib-hero--page), so this
   block does not rely on coming after section 6. */

/* -- Page hero: the home hero with a still image and a fixed band -------- */

.ib-hero.ib-hero--page {
  height: auto;
  min-height: 420px;
}

@media (min-width: 1024px) {
  .ib-hero.ib-hero--page {
    min-height: 512px;
  }
}

/* max-width is reset for the same reason as the home page's video: the Reset
   section caps every image at 100%, which this one must ignore to cover a
   viewport wider than the file. */
.ib-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  opacity: 0.55;
}

.ib-hero--page .ib-hero__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    #000 0%,
    rgba(0, 0, 0, 0.45) 55%,
    rgba(0, 0, 0, 0.15) 100%
  );
}

.ib-hero__crumbs {
  display: inline-block;
  color: rgba(255, 255, 255, 0.4);
  font-family: var(--ib-font-mono);
  font-size: 11px;
  line-height: 16px;
  letter-spacing: 0.06em;
}

.ib-hero__crumbs a {
  transition: color 0.15s;
}

.ib-hero__crumbs a:hover {
  color: var(--ib-primary);
}

.ib-hero__sep {
  font-style: normal;
}

/* 14px and 18px are not steps in the spacer scale, so they stay here. */
.ib-hero--page .ib-hero__title {
  margin: 14px 0 18px;
  font-size: clamp(2.75rem, 7vw, 6.5rem);
  line-height: 0.885;
  text-transform: uppercase;
}

.ib-hero--page .ib-hero__lede {
  max-width: 620px;
  font-size: 16px;
  line-height: 26px;
}

/* -- Compact page hero: breadcrumb and title only ------------------------ */

/* template-parts/page/hero-compact.php, used by page.php and Gallery. Every
   Figma inner page but Our Factory has a 334px band, so that is the height
   from 1024px; below that, which the design does not show, the band is as tall
   as its padding (py-14) and text. Three classes, so it wins over both
   .ib-hero.ib-hero--page rules above wherever this block ends up. */
.ib-hero.ib-hero--page.ib-hero--compact {
  min-height: 0;
}

@media (min-width: 1024px) {
  .ib-hero.ib-hero--page.ib-hero--compact {
    min-height: 334px;
  }
}

.ib-hero--compact .ib-hero__title {
  margin-bottom: 0;
}

/* As a block the trail is exactly its 16px line; inline-block adds 2px of line
   box under it, which put the title 2px lower than the design. */
.ib-hero--compact .ib-hero__crumbs {
  display: block;
}

/* -- Page body: the editor content page.php prints ------------------------ */

/* No design exists for a plain page yet. This keeps the body readable with
   the site's own type until one does: the full width of the page box, the
   heading face from section 3, and links in the brand colour.

   The width is the article's .container px-6 px-lg-14, the same box every
   other band and the footer sit in, so no max-width here.

   overflow-wrap lets a long unbroken string, such as a pasted link, wrap on a
   phone instead of running past the edge of the screen. */
.ib-page__content {
  color: var(--ib-text);
  font-size: 16px;
  line-height: 26px;
  overflow-wrap: anywhere;
}

.ib-page__content :where(table, iframe) {
  max-width: 100%;
}

.ib-page__content :where(p, ul, ol, blockquote, figure, table) {
  margin-block: 0 20px;
}

.ib-page__content :where(ul, ol) {
  padding-left: 1.25em;
}

.ib-page__content :where(h2, h3, h4) {
  margin-block: 40px 16px;
  color: var(--ib-text);
}

.ib-page__content > :first-child {
  margin-top: 0;
}

.ib-page__content > :last-child {
  margin-bottom: 0;
}

.ib-page__content h2 {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  line-height: 1;
}

.ib-page__content h3 {
  font-size: 1.5rem;
}

.ib-page__content h4 {
  font-size: 1.25rem;
}

.ib-page__content a {
  color: var(--ib-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ib-page__content a:hover {
  color: var(--ib-primary-hover);
}

.ib-page__content blockquote {
  padding-left: 20px;
  border-left: 3px solid var(--ib-primary);
  color: var(--ib-muted-text);
}

.ib-page__pages {
  margin-top: 32px;
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.06em;
}

/* -- Page Builder template: template-page-builder.php -------------------- */

/* No design. A builder (Elementor, Beaver Builder, raw HTML) gets the bare
   .ib-builder wrapper: no box, no spacing, full width. Block editor content
   (.ib-builder--blocks, which also takes the .ib-page__content type above)
   keeps each ordinary or Wide block in the page box, 1400px with 24px sides and
   56px from 1024px, and lets a Full width block run edge to edge. .ib-content's
   overflow-x: clip keeps a full-width section from scrolling sideways. */
.ib-builder--blocks > * {
  max-width: var(--ib-container);
  margin-inline: auto;
  padding-inline: 24px;
}

@media (min-width: 1024px) {
  .ib-builder--blocks > * {
    padding-inline: 56px;
  }
}

.ib-builder--blocks > .alignfull {
  max-width: none;
  padding-inline: 0;
}

/* 21. Page: Our Factory ================================================== */

/* Ported from the "Page: our-factory" block of html/style.css, with its class
   names. Layout is Bootstrap classes in the template parts; this block holds
   colour, type, size and the two grids Bootstrap has no class for.

   Self-contained on purpose. Every value is one of the --ib-* tokens above, no
   rule depends on where this block sits in the file, and a shared component is
   only ever narrowed through a scoped selector such as .ib-mfg .ib-h2. So the
   whole block can be cut into assets/css/pages/our-factory.css and enqueued
   from ib_page_styles() with nothing else to change.

   The header offset html/ needs is absent here: the theme already pushes the
   page down with .ib-sticky-header .ib-content. */

/* -- About India Bungy --------------------------------------------------- */

.ib-about-head p {
  margin: 0;
  max-width: 420px;
  color: var(--ib-muted-text);
  font-weight: 300;
  font-size: 16px;
  line-height: 26px;
}

/* The cards stretch to the tallest of the row, as the design has them. */
.ib-numcards {
  --bs-gap: 1rem;
  --bs-columns: 1;
}

@media (min-width: 1024px) {
  .ib-numcards {
    --bs-columns: 3;
  }
}

.ib-numcard {
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
}

.ib-numcard__num {
  display: block;
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 15px;
  letter-spacing: 0.1em;
}

.ib-numcard__icon {
  display: block;
  padding: 18px 0 16px;
  color: var(--ib-primary);
}

/* A 26px icon on the 24 grid: 1.6 draws the design's 1.733px stroke. */
.ib-numcard__icon .ib-icon {
  stroke-width: 1.6;
}

.ib-numcard p {
  margin: 0;
  color: var(--ib-muted-text);
  font-weight: 300;
  font-size: 15px;
  line-height: 24px;
}

/* -- Rotamoulding -------------------------------------------------------- */

.ib-rota {
  background: var(--ib-dark);
}

/* 28px: not a step in the Bootstrap spacer scale. */
.ib-rota__row {
  gap: 28px;
}

/* The 4px accent bar, shared with the history pull quote. */
.ib-rule-bar {
  flex: none;
  width: 4px;
  align-self: stretch;
  background: var(--ib-primary);
}

.ib-eyebrow--sentence {
  text-transform: none;
  letter-spacing: 0.14em;
}

.ib-h2--md {
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  line-height: 1.0625;
}

.ib-rota .ib-h2 {
  color: #fff;
}

.ib-rota .ib-h2 em {
  font-style: normal;
  color: var(--ib-primary);
}

.ib-rota p {
  margin: 18px 0 0;
  max-width: 900px;
  color: rgba(255, 255, 255, 0.6);
  font-weight: 300;
  font-size: 16px;
  line-height: 26px;
}

/* -- History ------------------------------------------------------------- */

.ib-history {
  background: var(--ib-secondary);
}

.ib-timeline {
  --bs-gap: 1.5rem;
  --bs-columns: 1;
  align-items: start;
}

@media (min-width: 640px) {
  .ib-timeline {
    --bs-columns: 2;
  }
}

@media (min-width: 1024px) {
  .ib-timeline {
    --bs-columns: 4;
  }
}

.ib-timeline__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--ib-muted);
}

.ib-timeline__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ib-timeline__rule {
  display: block;
  position: relative;
  height: 9px;
  margin: 20px 0 18px;
}

.ib-timeline__rule::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 4px;
  height: 1px;
  background: rgba(0, 0, 0, 0.14);
}

.ib-timeline__rule::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 9px;
  height: 9px;
  background: var(--ib-primary);
}

/* The Base section sets every heading in capitals; a year is typed as it is
   meant to read, so "Today" stays "Today". */
.ib-timeline__year {
  margin: 0;
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-weight: 900;
  font-size: 64px;
  line-height: 1;
  text-transform: none;
}

.ib-timeline__item p {
  margin: 12px 0 0;
  color: var(--ib-muted-text);
  font-weight: 300;
  font-size: 15px;
  line-height: 24px;
}

.ib-pullquote {
  padding-top: 40px;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
}

.ib-pullquote blockquote {
  margin: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-weight: 900;
  font-size: clamp(1.5rem, 2.6vw, 2.125rem);
  line-height: 1.147;
  text-transform: uppercase;
}

/* -- Manufacturing ------------------------------------------------------- */

.ib-mfg {
  background: var(--ib-dark);
  color: #fff;
}

/* MANUFACTURING is one long word: a lower floor than .ib-h2's keeps it inside
   a 320px screen. 64px, the design value, still applies from 1067px up. */
.ib-mfg .ib-h2 {
  color: #fff;
  font-size: clamp(2rem, 6vw, 4rem);
}

/* 26, 22 and 36 are not steps in the spacer scale. */
.ib-mfg p {
  margin: 26px 0 0;
  max-width: 660px;
  color: rgba(255, 255, 255, 0.6);
  font-weight: 300;
  font-size: 16px;
  line-height: 26px;
}

.ib-mfg p + p {
  margin-top: 22px;
}

.ib-mfg strong {
  color: #fff;
  font-weight: 600;
}

.ib-mfg__stats {
  --bs-columns: 1;
  margin-top: 36px;
  max-width: 660px;
}

@media (min-width: 640px) {
  .ib-mfg__stats {
    --bs-columns: 3;
  }
}

/* The design fixes the left column at 620px, which sets the band's height. */
@media (min-width: 1024px) {
  .ib-mfg {
    min-height: 620px;
  }
}

.ib-map {
  background: #1c1c1c;
  min-height: 320px;
}

.ib-map iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 320px;
  border: 0;
  filter: grayscale(1) contrast(1.05) brightness(0.85);
}

/* -- Gallery: this page's mosaic ---------------------------------------- */

/* 424 / 208 / 208 / 424 columns, two 266px rows, the first tile spanning both.
   Six pictures leave the bottom-right cell open, as the design has it; a
   seventh fills it.

   Four columns here against the home page's six, so the tiles the home mosaic
   widens are reset to one column: at these widths every tile but the first
   occupies a single cell. Without that, the seventh needs two columns, cannot
   fit beside the sixth, and drops into a third row that the fixed height
   flattens to nothing. */
@media (min-width: 1024px) {
  .ib-gallery__grid--wide {
    grid-template-columns: 53fr 26fr 26fr 53fr;
  }

  .ib-gallery__grid--wide .ib-gallery__item:nth-child(1) {
    grid-column: span 1;
    grid-row: span 2;
  }

  .ib-gallery__grid--wide .ib-gallery__item:nth-child(4),
  .ib-gallery__grid--wide .ib-gallery__item:nth-child(7) {
    grid-column: span 1;
  }
}

/* 22. Page: Gallery ====================================================== */

/* Ported from the "Page: gallery" block of html/style.css, with its class
   names. The hero is the shared compact one (section 20) and each tile is the
   home page's .ib-gallery__item; this block holds the justified rows and the
   photo viewer. Values from Figma nodes 127:2 and 213:2.

   Self-contained like section 21: tokens only, nothing that depends on where
   the block sits, and component names (.ib-justified, .ib-lightbox) any later
   page can reuse. */

/* -- Photo grid: justified rows ------------------------------------------ */

/* Each photo grows by its own width-to-height ratio (--w/--h, the file's size)
   from a zero basis, so a row fills the box and every photo in it gets the
   same height. 10px is not a spacer step. Below 768px the rows stack and each
   photo keeps its ratio at full width. The tiles are buttons, so the browser's
   padding is cleared. */
.ib-justified,
.ib-justified__row {
  gap: 10px;
}

.ib-justified__item {
  padding: 0;
  aspect-ratio: var(--w) / var(--h);
  cursor: zoom-in;
}

/* Stands in for the missing photos of a short last row (theme only; html/
   always has full rows). Hidden on phones, where rows stack. */
.ib-justified__fill {
  display: none;
}

@media (min-width: 768px) {
  .ib-justified__item,
  .ib-justified__fill {
    display: block;
    flex-grow: calc(var(--w) / var(--h));
    flex-shrink: 1;
    flex-basis: 0;
    min-width: 0;
  }
}

/* -- Photo viewer -------------------------------------------------------- */

/* Display lives here, not in a d-flex class: Bootstrap's utilities are
   !important and would beat the hidden attribute. Above the fixed header
   (1030) and the floating WhatsApp button (1040).

   The photo sits in a box 76% of the screen tall, as in Figma node 213:2
   (684px on a 900px screen), so a small file is scaled up and the counter
   always lands in the same place. On a phone the box is the screen's width,
   capped at 66% of its height. */
.ib-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1050;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 72px 24px;
  background: rgba(10, 10, 10, 0.97);
  opacity: 0;
  transition: opacity 0.25s ease;
}

.ib-lightbox[hidden] {
  display: none;
}

.ib-lightbox.is-open {
  opacity: 1;
}

.ib-lightbox__figure {
  gap: 18px;
  max-width: 92vw;
  max-height: 100%;
}

.ib-lightbox__img {
  display: block;
  width: auto;
  height: 76vh;
  max-width: 92vw;
  object-fit: contain;
}

.ib-lightbox__count {
  color: var(--ib-primary);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.18em;
}

.ib-lightbox__btn {
  position: absolute;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  transition:
    border-color 0.2s,
    color 0.2s;
}

.ib-lightbox__btn:hover,
.ib-lightbox__btn:focus-visible {
  border-color: var(--ib-primary);
  color: var(--ib-primary);
}

.ib-lightbox__close {
  top: 24px;
  right: 24px;
}

.ib-lightbox__prev,
.ib-lightbox__next {
  top: 50%;
  transform: translateY(-50%);
}

.ib-lightbox__prev {
  left: 24px;
}

.ib-lightbox__next {
  right: 24px;
}

@media (max-width: 767.98px) {
  .ib-lightbox {
    padding: 64px 12px;
  }

  .ib-lightbox__btn {
    width: 44px;
    height: 44px;
  }

  .ib-lightbox__prev {
    left: 12px;
  }

  .ib-lightbox__next {
    right: 12px;
  }

  .ib-lightbox__img {
    width: 92vw;
    height: auto;
    max-height: 66vh;
  }
}

/* 23. Page: Clients ====================================================== */

/* The Clients page uses shared pieces only: the compact hero (section 20)
   and the brochure client list, .ib-network (section 29). The region rail
   and filtered directory that stood here were removed with the filter. */

/* 24. Page: Contact Us =================================================== */

/* Ported from the "Page: contact-us" block of html/style.css, with its class
   names. The hero is the shared compact one (section 20), the headings the
   shared .ib-eyebrow and .ib-h2, the form section 15's .ib-form. This block
   holds the action cards, the office list, the quote card and the map band.
   Values from Figma node 166:2.

   One difference from html: the map is the live Google embed, as on Our
   Factory, where html shows a still image.

   Self-contained like sections 21 to 23: tokens only, selectors scoped where a
   shared component is narrowed, and component names (.ib-actioncard,
   .ib-infolist, .ib-quote) any later page can reuse. */

/* -- Shared pieces ------------------------------------------------------- */

/* 10px under the label, where the home eyebrow has 12. */
.ib-eyebrow.ib-eyebrow--tight {
  margin-bottom: 10px;
}

.ib-h2 em {
  color: var(--ib-primary);
  font-style: normal;
}

/* -- Action cards -------------------------------------------------------- */

/* Four across from 1024px, two from 640px, one below; 221px high, the parts
   spread over the height as the design has them. */
.ib-actioncards {
  --bs-columns: 1;
  --bs-gap: 16px;
}

@media (min-width: 640px) {
  .ib-actioncards {
    --bs-columns: 2;
  }
}

@media (min-width: 1024px) {
  .ib-actioncards {
    --bs-columns: 4;
  }
}

.ib-actioncard {
  min-height: 221px;
  gap: 14px;
  padding: 28px 24px 24px;
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
}

.ib-actioncard__icon {
  width: 44px;
  height: 44px;
  border: 1px solid var(--ib-border);
  color: var(--ib-primary);
}

.ib-actioncard__k {
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-actioncard__v {
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 18px;
  font-weight: 700;
  line-height: 24px;
  overflow-wrap: anywhere;
}

.ib-actioncard__link {
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-size: 12px;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.ib-actioncard__link .ib-icon--arrow {
  transition: transform 0.2s ease;
}

.ib-actioncard__link:hover .ib-icon--arrow {
  transform: translateX(4px);
}

/* -- Details and enquiry ------------------------------------------------- */

/* 566 : 650 with a 72px gap from 1024px, as the design; stacked below. */
.ib-details {
  --bs-columns: 1;
  --bs-gap: 64px 72px;
  align-items: start;
}

@media (min-width: 1024px) {
  .ib-details {
    grid-template-columns: minmax(0, 566fr) minmax(0, 650fr);
  }

  /* Office details or form alone, when the other is left empty. */
  .ib-details.ib-details--single {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ib-office__name {
  margin: 28px 0 8px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 22px;
  font-weight: 900;
  line-height: 26px;
  text-transform: uppercase;
}

.ib-office__note {
  margin: 0 0 8px;
  color: var(--ib-muted-text);
  font-size: 16px;
  font-weight: 300;
  line-height: 26px;
}

.ib-office__social {
  gap: 10px;
  padding-top: 28px;
}

.ib-office__social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--ib-border);
  color: var(--ib-text);
  transition: all 0.2s ease;
}

.ib-office__social a:hover {
  border-color: var(--ib-primary);
  color: var(--ib-primary);
}

.ib-infolist {
  border-top: 1px solid var(--ib-border);
}

.ib-infolist__row {
  gap: 18px;
  padding: 22px 0;
  border-bottom: 1px solid var(--ib-border);
}

.ib-infolist__icon {
  width: 40px;
  height: 40px;
  border: 1px solid var(--ib-border);
  color: var(--ib-primary);
}

.ib-infolist__k {
  margin-bottom: 4px;
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  font-weight: 400;
  line-height: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-infolist__v {
  color: var(--ib-text);
  font-size: 15px;
  font-weight: 600;
  line-height: 24px;
  overflow-wrap: anywhere;
}

a.ib-infolist__v {
  transition: color 0.15s ease;
}

a.ib-infolist__v:hover {
  color: var(--ib-primary);
}

.ib-quote {
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
}

.ib-quote .ib-form__title {
  margin-bottom: 6px;
}

.ib-quote__lede {
  margin: 0 0 28px;
  color: var(--ib-muted-text);
  font-size: 15px;
  font-weight: 300;
  line-height: 24px;
}

/* -- Map ----------------------------------------------------------------- */

.ib-mapband {
  background: var(--ib-secondary);
  border-top: 1px solid var(--ib-border);
}

/* 35.2px, below the smallest shared .ib-h2 size, on the same .9 line. */
.ib-mapband .ib-h2 {
  font-size: 2.2rem;
  line-height: 0.9;
}

.ib-link-more.ib-mapband__link {
  gap: 9px;
  padding: 12px 0;
  color: var(--ib-primary);
  letter-spacing: 0.12em;
}

/* The live map in the design's 320px bordered box, grey like the design's
   still, without Our Factory's darkening. */
.ib-mapband__map {
  height: 320px;
  border: 1px solid var(--ib-border);
  background: var(--ib-muted);
}

.ib-mapband__map iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  filter: grayscale(1);
}

/* 25. Page: Blog ========================================================= */

/* Ported from the "Page: blog" block of html/style.css, with its class names.
   The hero is the shared compact one (section 20), the contact band section
   15, the link .ib-link-more. This block holds the post cards, their meta line
   and the pager. Values from Figma node 136:2.

   Self-contained like sections 21 to 24: tokens only, selectors scoped where a
   shared component is narrowed, and component names (.ib-postcard,
   .ib-postmeta, .ib-pager) any later page can reuse. */

/* -- Post cards ---------------------------------------------------------- */

/* Three across from 1024px, two from 768px, one below, 24px apart. A card
   stretches to the tallest in its row; the link sits at its foot, at least
   48px (mb-12) under the excerpt, which gives the design's 618.64px card. */
.ib-postcards {
  --bs-columns: 1;
  --bs-gap: 24px;
}

@media (min-width: 768px) {
  .ib-postcards {
    --bs-columns: 2;
  }
}

@media (min-width: 1024px) {
  .ib-postcards {
    --bs-columns: 3;
  }
}

.ib-postcard {
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
}

.ib-postcard__media {
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--ib-muted);
}

.ib-postcard__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.9;
}

.ib-postcard__body {
  padding: 30px;
}

.ib-postcard__title {
  margin: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 25.6px;
  font-weight: 900;
  line-height: 28.2px;
  text-transform: uppercase;
}

/* html gives the title link no hover colour; the theme's base a:hover would. */
.ib-postcard__title a:hover {
  color: inherit;
}

.ib-postcard__excerpt {
  margin-top: 12px;
  color: var(--ib-muted-text);
  font-size: 15px;
  font-weight: 300;
  line-height: 24px;
}

.ib-link-more.ib-postcard__more {
  color: var(--ib-primary);
}

/* -- Post meta: category chip and date ----------------------------------- */

.ib-postmeta {
  gap: 10px;
  margin-bottom: 14px;
}

.ib-postmeta__chip,
.ib-postmeta__date {
  font-family: var(--ib-font-mono);
  font-size: 10px;
  line-height: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ib-postmeta__chip {
  padding: 5px 10px;
  background: var(--ib-primary);
  color: #fff;
  font-weight: 500;
}

.ib-postmeta__date {
  color: var(--ib-muted-text);
  font-weight: 400;
}

/* -- Pager --------------------------------------------------------------- */

/* 46px squares 6px apart under a rule; the current page in the brand colour,
   an unavailable arrow at 30%. */
.ib-pager {
  gap: 6px;
  border-top: 1px solid var(--ib-border);
}

.ib-pager__item,
.ib-pager__dots {
  height: 46px;
  font-family: var(--ib-font-head);
  font-size: 15px;
  font-weight: 700;
  line-height: 24px;
  letter-spacing: 0.06em;
}

.ib-pager__item {
  width: 46px;
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
  color: var(--ib-text);
}

.ib-pager__item.is-current {
  background: var(--ib-primary);
  border-color: var(--ib-primary);
  color: #fff;
}

.ib-pager__item.is-disabled {
  opacity: 0.3;
}

.ib-pager__dots {
  width: 26px;
  color: var(--ib-muted-text);
}

/* 26. Page: Blog single ================================================== */

/* Ported from the "Page: blog single" block of html/style.css, with its class
   names. The hero is the shared page hero (section 20) with the trail, the
   meta line .ib-postmeta (section 25) and the link .ib-link-more. This block
   holds the post hero modifier, the featured image, the post body and the
   previous / next row. Values from Figma node 151:2.

   Self-contained like sections 21 to 25: tokens only, selectors scoped where a
   shared component is narrowed, and component names (.ib-prose, .ib-postimage,
   .ib-postnav) any later page can reuse. */

/* -- Post hero: dark band, no image -------------------------------------- */

/* The trail starts 132px down from 1024px (56px below). The foot is 56px of
   space plus the part of the featured image that overlaps the band: 72px from
   768px, 40px below. Three classes, so it wins over .ib-hero.ib-hero--page. */
.ib-hero.ib-hero--page.ib-hero--post {
  min-height: 0;
  background: var(--ib-text);
}

.ib-hero--post .ib-hero__body {
  padding-top: 56px;
  padding-bottom: 96px;
}

@media (min-width: 768px) {
  .ib-hero--post .ib-hero__body {
    padding-bottom: 128px;
  }
}

@media (min-width: 1024px) {
  .ib-hero--post .ib-hero__body {
    padding-top: 132px;
  }
}

/* As a block the trail is its 16px line, as on the compact hero. */
.ib-hero--post .ib-hero__crumbs {
  display: block;
}

.ib-hero--post .ib-postmeta {
  margin-bottom: 18px;
}

/* 57.6/59.9 from 1024px, scaled down below it; the design has no mobile frame. */
.ib-hero.ib-hero--post .ib-hero__title {
  max-width: 700px;
  margin: 0;
  font-size: clamp(2.25rem, 1.25rem + 4.2vw, 3.6rem);
  line-height: 1.04;
  text-transform: uppercase;
}

/* A post without a featured image: no image overlaps the band, so it closes
   56px under the title at every width. */
.ib-hero--post.ib-hero--noimage .ib-hero__body {
  padding-bottom: 56px;
}

/* -- Post meta on a dark band -------------------------------------------- */

.ib-postmeta--dark .ib-postmeta__date {
  color: rgba(255, 255, 255, 0.45);
}

/* -- Featured image: pulled up over the hero ------------------------------ */

/* flow-root keeps the image's negative margin inside the article, so the
   article's background does not cover the foot of the hero. */
.ib-article {
  display: flow-root;
}

.ib-postimage {
  position: relative;
  z-index: 10;
  margin: -40px 0 0;
  aspect-ratio: 16 / 7;
  overflow: hidden;
  background: var(--ib-muted);
}

@media (min-width: 768px) {
  .ib-postimage {
    margin-top: -72px;
  }
}

.ib-postimage img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* -- Post body ----------------------------------------------------------- */

/* Plain post markup. Blocks sit 22px apart, a heading 48px under the block
   above it and 18px over the next; flow-root keeps the last block's 22px
   inside, which with mt-16 on the row below gives the design's gap. */
.ib-prose {
  display: flow-root;
  max-width: 900px;
  color: var(--ib-text);
  font-size: 16px;
  font-weight: 300;
  line-height: 28px;
}

.ib-prose p,
.ib-prose ul,
.ib-prose ol {
  margin: 0 0 22px;
}

.ib-prose .ib-lead {
  font-size: 18px;
  line-height: 31px;
}

.ib-prose strong {
  font-weight: 600;
}

.ib-prose h2 {
  margin: 48px 0 18px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 32.8px;
  font-weight: 900;
  line-height: 35.42px;
  text-transform: uppercase;
}

.ib-prose > :first-child {
  margin-top: 0;
}

/* Not in the design; the posts use them. A sub-heading one step down, links
   in the brand colour, a plain rule, and italic slanted by the browser, since
   no italic Barlow file is shipped and :root turns synthesis off. */
.ib-prose h3 {
  margin: 36px 0 14px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 24px;
  font-weight: 800;
  line-height: 28px;
  text-transform: uppercase;
}

.ib-prose a {
  color: var(--ib-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.15s;
}

.ib-prose a:hover {
  color: var(--ib-primary-hover);
}

.ib-prose hr {
  margin: 40px 0;
  border: 0;
  border-top: 1px solid var(--ib-border);
  opacity: 1;
}

.ib-prose em {
  font-style: italic;
  font-synthesis: style;
}

/* Lists: a 7px square in the brand colour, or a two-digit number. */
.ib-prose ul,
.ib-prose ol {
  padding: 0;
  list-style: none;
}

.ib-prose li {
  position: relative;
  padding-left: 26px;
}

.ib-prose li + li {
  margin-top: 10px;
}

.ib-prose ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 11px;
  width: 7px;
  height: 7px;
  background: var(--ib-primary);
}

.ib-prose ol {
  counter-reset: ib-step;
}

.ib-prose ol > li {
  padding-left: 38px;
  counter-increment: ib-step;
}

.ib-prose ol > li::before {
  content: counter(ib-step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  color: var(--ib-primary);
  font-family: var(--ib-font-head);
  font-size: 16px;
  font-weight: 900;
  line-height: 28px;
}

/* -- Previous / next post ------------------------------------------------ */

/* 44px links between two rules, 18px of space each side: 82px in all. */
.ib-postnav {
  max-width: 900px;
  padding: 18px 0;
  border-top: 1px solid var(--ib-border);
  border-bottom: 1px solid var(--ib-border);
}

.ib-postnav .ib-link-more {
  min-height: 44px;
}

/* 27. Page: 404 ========================================================== */

/* Ported from the "Page: 404" block of html/style.css, with its class names.
   The header, footer, eyebrow and the solid button are sections above, reused;
   this block holds the outlined code, the message and the requested address.
   Values from Figma node 278:123 (desktop only; below 1024px the columns stack
   and the code scales down).

   Self-contained like sections 21 to 26: tokens only, and shared components
   narrowed through scoped selectors (.ib-notfound .ib-btn). */

.ib-notfound .ib-eyebrow {
  margin-bottom: 14px;
}

@media (min-width: 1024px) {
  .ib-notfound__col {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* -- The code: 404 in a faint outline, its middle 0 again in orange ------- */

/* Two text layers as in Figma: the orange 0 sits 162px in at the design's
   304px, which is .533em at any size. */
.ib-notfound__code {
  position: relative;
  margin: 0;
  color: transparent;
  font-family: var(--ib-font-head);
  font-size: clamp(8rem, 21vw, 19rem);
  font-weight: 900;
  line-height: 1.2;
  letter-spacing: -0.03em;
  white-space: nowrap;
  -webkit-text-stroke: 2px rgba(0, 0, 0, 0.14);
}

.ib-notfound__zero {
  position: absolute;
  left: 0.533em;
  top: 0;
  -webkit-text-stroke-color: var(--ib-primary);
}

/* Stacked below 1024px the line box hugs the letters, so the space above the
   code matches the space below the band and the gap to the message is 32px. */
@media (max-width: 1023.98px) {
  .ib-notfound__code {
    line-height: 0.76;
  }
}

/* -- Message ------------------------------------------------------------- */

.ib-notfound__title {
  margin: 0 0 20px;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: clamp(2.5rem, 1.5rem + 3.2vw, 3.6rem);
  font-weight: 900;
  line-height: 0.94;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.ib-notfound__text {
  max-width: 410px;
  margin: 0 0 36px;
  color: var(--ib-muted-text);
  font-size: 16px;
  font-weight: 300;
  line-height: 28px;
}

/* The design's button is 4px narrower each side, with 10px to the icon. */
.ib-notfound .ib-btn {
  padding: 16px 28px;
  gap: 10px;
}

.ib-notfound__url {
  margin: 32px 0 0;
  color: rgba(17, 17, 17, 0.35);
  font-family: var(--ib-font-mono);
  font-size: 10px;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

/* 28. Search results ===================================================== */

/* search.php and searchform.php, built in the theme without an html/ page or
   a Figma frame (the user's choice). Everything else is reused: the compact
   hero (20), the field look of the contact form (.ib-form), the solid button
   (7), the chip and date (.ib-postmeta) and pager (25) and the shop's empty
   line (.ib-cat-empty, 18). This block sizes the form and styles the result
   count and the result rows (template-parts/search/result.php).

   The field and button share one 52px row from 640px, at most 720px wide;
   below 640px they stack at full width. */
.ib-searchform {
  max-width: 720px;
  margin-bottom: 40px;
}

.ib-searchform input {
  flex: 1 1 auto;
  min-width: 0;
  height: 52px;
  -webkit-appearance: none;
  appearance: none;
}

.ib-searchform .ib-btn {
  flex: none;
}

/* The shop toolbar's count style: DM Mono 11/16, spaced, uppercase. */
.ib-search__count {
  margin: 0 0 28px;
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 11px;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* -- Result rows --------------------------------------------------------- */

/* One white box, the blog card's surface and border, split into full-width
   rows by a rule. No image; the text keeps a readable 820px measure. The
   title takes the brand colour on hover, as a link would. */
.ib-results {
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
}

.ib-result {
  padding: 24px;
}

.ib-result + .ib-result {
  border-top: 1px solid var(--ib-border);
}

@media (min-width: 768px) {
  .ib-result {
    padding: 32px 40px;
  }
}

.ib-result .ib-postmeta {
  margin-bottom: 12px;
}

.ib-result__title {
  max-width: 820px;
  margin: 0;
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 22px;
  font-weight: 900;
  line-height: 26px;
  text-transform: uppercase;
}

@media (min-width: 768px) {
  .ib-result__title {
    font-size: 25.6px;
    line-height: 28.2px;
  }
}

.ib-result__title a {
  transition: color 0.15s ease;
}

.ib-result__excerpt {
  max-width: 820px;
  margin: 10px 0 0;
  color: var(--ib-muted-text);
  font-size: 15px;
  font-weight: 300;
  line-height: 24px;
}

.ib-link-more.ib-result__more {
  margin-top: 18px;
  color: var(--ib-primary);
}

.ib-link-more.ib-result__more:hover {
  color: var(--ib-primary-hover);
}

/* 29. Client network (home and Clients page) ============================= */

/* The client list as the brochure lays it out ("Our Client Network"): one
   block per region with a red bar before its name and a rule under it, one
   row per client with the city on the right, every second row shaded. Used
   by the home "Brochure list" (template-parts/home/clients-network.php, a
   .ib-network__cols grid) and the Clients page (template-parts/clients/
   network.php, that grid or the two-column .ib-network__flow, by its Layout
   field). Not in html/ yet.

   The brochure sets the city in italic grey. The theme loads no italic face
   and sets font-synthesis:none, so the city is set in the grey mono. */

/* Regions are the grid's children: one column, two from 768px, and from
   1280px a six-track grid, three regions to a row (two tracks each). The last
   row adapts to the count, with no script: two left over share the row
   (3-2, and 2 alone is 2), one left over turns the last four into two pairs
   (4 is 2-2, 7 is 3-2-2), a single region takes the full width. 3 and 6
   stay 3 and 3-3. At 1024px three columns would squeeze the names against
   the cities, so 768-1279px keeps two columns, an odd last region taking the
   full row. Any region on a full row lays its list out in two columns. */
.ib-network__cols {
  --bs-columns: 1;
  --bs-gap: 48px 40px;
}

@media (min-width: 768px) {
  .ib-network__cols {
    --bs-columns: 2;
  }
}

/* Two columns: an odd region left over takes the full row. The grid rules
   are scoped to .ib-network__cols so the flowing layout below is left alone. */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .ib-network__cols > .ib-network__region:nth-child(odd):last-child {
    grid-column: span 2;
  }
}

/* A region on a full row splits its own list in two, so a name and its city
   are never a full container apart. */
@media (min-width: 768px) {
  .ib-network__cols > .ib-network__region:only-child .ib-network__list {
    column-count: 2;
    column-gap: 40px;
  }
}

@media (min-width: 768px) and (max-width: 1279.98px) {
  .ib-network__cols > .ib-network__region:nth-child(odd):last-child .ib-network__list {
    column-count: 2;
    column-gap: 40px;
  }
}

.ib-network__row {
  break-inside: avoid;
}

@media (min-width: 1280px) {
  .ib-network__cols {
    --bs-columns: 6;
  }

  .ib-network__cols > .ib-network__region {
    grid-column: span 2;
  }

  /* Count 3n+2: the last two. */
  .ib-network__cols > .ib-network__region:nth-child(3n + 1):nth-last-child(2),
  .ib-network__cols > .ib-network__region:nth-child(3n + 2):last-child,
  /* Count 3n+1 (4 or more): the last four. */
  .ib-network__cols > .ib-network__region:nth-child(3n + 1):nth-last-child(4),
  .ib-network__cols > .ib-network__region:nth-child(3n + 2):nth-last-child(3),
  .ib-network__cols > .ib-network__region:nth-child(3n + 3):nth-last-child(2),
  .ib-network__cols > .ib-network__region:nth-child(3n + 4):last-child {
    grid-column: span 3;
  }

  .ib-network__cols > .ib-network__region:only-child {
    grid-column: span 6;
  }
}

/* The Clients page's full list: the regions flow down two balanced columns
   from 768px, as in the brochure (North, East, South | West, International
   with the brochure's counts), one below. A region never splits across the
   columns; the browser balances them, so a longer or shorter list still
   evens out. */
.ib-network__flow > .ib-network__region {
  margin-bottom: 48px;
  break-inside: avoid;
}

.ib-network__flow > .ib-network__region:last-child {
  margin-bottom: 0;
}

/* The margin of the region ending the first column falls at the column
   break, where the browser truncates it, so the columns stay top-aligned. */
@media (min-width: 768px) {
  .ib-network__flow {
    column-count: 2;
    column-gap: 64px;
  }
}

.ib-network__title {
  margin: 0 0 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--ib-border);
  color: var(--ib-text);
  font-family: var(--ib-font-head);
  font-size: 26px;
  font-weight: 800;
  line-height: 28px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.ib-network__title i {
  flex: none;
  width: 28px;
  height: 4px;
  background: var(--ib-primary);
}

.ib-network__row {
  padding: 7px 12px;
}

.ib-network__row:nth-child(even) {
  background: var(--ib-secondary);
}

.ib-network__name {
  flex: 1 1 0;
  min-width: 0;
  color: rgba(17, 17, 17, 0.85);
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
}

/* Muted text token rather than a 45% grey, which the client found too light
   (about 3:1 on the shaded rows); this is above 5:1 on both. */
.ib-network__city {
  flex: none;
  max-width: 45%;
  color: var(--ib-muted-text);
  font-family: var(--ib-font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0.08em;
  text-align: right;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .ib-wa-float:hover {
    transform: none;
  }

  /* Reveals resolve immediately rather than sliding. */
  .ib-js .ib-reveal {
    opacity: 1;
    transform: none;
  }
}
