/*
 * Utility and WordPress-adjustment rules the design assumes exist.
 *
 * Carried over whole from the retired theme's wp-adjustments.css, plus the four
 * utilities at the end of its globals.css. They did not come across with the
 * component stylesheets because they belong to no component — which is exactly
 * why nobody noticed they were gone, and why every one of them was missing from
 * every page of the rebuilt site.
 *
 * What was actually broken, not hypothetically:
 *
 *   .np-fill              np_image() puts this on every image the Next.js build
 *                         rendered with `fill`, and it *is* that positioning.
 *                         Without it those images lay out as ordinary elements:
 *                         on a case study hero it pushed the gradient overlay
 *                         outside the viewport, giving five pixels of sideways
 *                         scroll on every case study page, and it applies to
 *                         every card thumbnail and banner on the site.
 *
 *   screen-reader-text    Text meant only for a screen reader was drawn on the
 *   .visually-hidden      page.
 *
 *   .skip-link            The keyboard skip target had no offscreen position,
 *                         so it could not work as intended.
 *
 *   :focus-visible        No visible focus ring beyond the browser default.
 *
 *   reduced motion        The home hero's entrance animations ignored
 *                         `prefers-reduced-motion` entirely.
 *
 *   [hidden] rules        A component rule setting `display` outranks the UA
 *                         stylesheet's `[hidden]`, so elements the scripts hide
 *                         stayed visible. Two of the four selectors below are
 *                         for the retired client-side industry filter and are
 *                         now inert; the testimonial and mobile-submenu ones
 *                         are still live.
 *
 * Enqueued site-wide by the child theme rather than declared by any widget:
 * nothing owns them, and every page needs them.
 */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -48px;
  background: var(--navy);
  color: #fff;
  padding: 10px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  z-index: 1000;
  transition: top 0.2s;
}

.skip-link:focus {
  top: 12px;
}

:focus-visible {
  outline: 2px solid var(--green2);
  outline-offset: 2px;
}

.np-fill {
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  color: transparent;
}

/*
 * WordPress core's accessibility helper. The Next.js build used
 * `.visually-hidden` (kept in globals.css); core markup and the skip link
 * emitted by some plugins use `.screen-reader-text`, so both are supported.
 */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.screen-reader-text:focus {
  top: 12px;
  left: 12px;
  z-index: 1000;
  width: auto;
  height: auto;
  clip: auto;
  clip-path: none;
  padding: 10px 16px;
  border-radius: 4px;
  background: var(--navy);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}

/*
 * Core block alignment classes. The converted layouts set their own widths, so
 * these only need to behave sensibly for content an editor adds inside the
 * post body.
 */
.alignleft {
  float: left;
  margin: 0 1.5em 1em 0;
}

.alignright {
  float: right;
  margin: 0 0 1em 1.5em;
}

.aligncenter {
  margin-left: auto;
  margin-right: auto;
}

.alignwide,
.alignfull {
  max-width: none;
}

/* Core wraps captioned images in a figure that must not break the grid. */
.wp-caption,
.wp-block-image figure {
  max-width: 100%;
}

.wp-caption-text,
.wp-block-image figcaption {
  font-size: 13px;
  color: var(--muted);
  margin-top: 8px;
}

/*
 * Gutenberg emits an empty <p> for a blank paragraph block; the converted
 * layouts rely on explicit spacing, so a stray empty paragraph would add a
 * phantom gap.
 */
.np-content-blocks__content p:empty,
.np-article-blocks__article p:empty {
  display: none;
}

/*
 * Core heading and image blocks inside the product content wrapper.
 *
 * ContentBlocks.tsx wrapped every heading in a `.headingBlock` div and every
 * image in an `.imageBlock` div purely to carry margins — the h2 itself was
 * `margin: 0`. An editor writing a core heading block gets a bare <h2>, so the
 * same margins are applied directly here. Same idea for images.
 */
.np-content-blocks__content > h2 {
  margin: 36px 0 14px;
}

/*
 * The converted stylesheet carries `.np-content-blocks__content h2:first-child
 * { margin-top: 0 }` from the original. In React that selector only ever
 * matched an h2 sitting inside its own `.headingBlock` wrapper, where the h2's
 * margin was already zero and the spacing came from the wrapper — so it did
 * nothing. With core heading blocks the h2 really is the first child of the
 * content wrapper, so the rule starts biting and swallows 36px of leading
 * space. This restores it, at matching specificity, later in the cascade.
 */
.np-content-blocks__content > h2:first-child {
  margin-top: 36px;
}

/*
 * Image blocks, as widgets.
 *
 * These were written with a child combinator, for a core image block sitting
 * directly in the wrapper. After the body conversion each block is an Elementor
 * Image widget instead, so `> figure.wp-block-image` reached nothing and every
 * image in a product body lost its spacing.
 */
/*
 * `.elementor-widget` is in these selectors to reach three classes.
 *
 * Elementor zeroes every widget's block margin inside a container with
 * `.e-con .elementor-widget.elementor-widget` — the class repeated purely for
 * weight — so a two-class rule sets a widget's top margin and silently loses
 * its bottom one. That is why the mark below sat flush against the heading
 * after its top margin had already come right.
 */
.np-content-blocks__content .elementor-widget.elementor-widget-image {
  margin: 24px 0 8px;
  display: flex;
  justify-content: flex-start;
}

.np-content-blocks__content .elementor-widget-image img {
  height: auto;
  max-width: 100%;
}

/*
 * The NanoPrep mark that sits directly above the "A new class of coating"
 * heading. In React this lived inside the heading's grid wrapper with a 14px
 * gap; as a preceding image block the same spacing comes from its own bottom
 * margin and the heading collapsing its top margin.
 */
.np-content-blocks__content .elementor-widget.np-heading-logo {
  margin: 36px 0 14px;
}

.np-content-blocks__content .np-heading-logo + .elementor-widget-heading h2 {
  margin-top: 0;
}

/*
 * `prefers-reduced-motion` was honoured implicitly in the Next.js build by the
 * animation library defaults. The vanilla JS replacements are explicit about
 * it, and this covers the CSS-driven entrance animation.
 */
@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;
  }
}

/*
 * Mobile menu icon swap.
 *
 * React re-rendered a single <svg> when the menu opened. The PHP template
 * renders both and lets CSS pick, driven by the button's `aria-expanded` —
 * that keeps the accessible state and the visual state impossible to
 * disagree, and means the JS only toggles one attribute.
 */
.np-mobile-menu__menu-toggle [data-np-icon="close"],
.np-mobile-menu__menu-toggle[aria-expanded="true"] [data-np-icon="open"] {
  display: none;
}

.np-mobile-menu__menu-toggle[aria-expanded="true"] [data-np-icon="close"] {
  display: block;
}

/*
 * Elements the scripts show and hide with the `hidden` attribute.
 *
 * The UA stylesheet's `[hidden] { display: none }` is a type-less, class-less
 * rule, so any component rule that sets `display` (flex, grid, block) beats it
 * and the element stays visible. Every element toggled by `hidden` therefore
 * needs its own rule at component specificity.
 */
.np-mobile-menu__sub-group[hidden],
.np-industry-filter__grid[hidden],
.np-case-study-card__card[hidden],
.np-testimonials__card[hidden] {
  display: none;
}

/*
 * Loop Grid: one gap on both axes.
 *
 * Elementor's Loop Grid exposes a row gap and no column gap, and defaults the
 * column axis to 30px. Every grid in this design uses a single value on both
 * axes — 24px, or 28px on the case studies filter — so the column gap follows
 * whatever the row gap is set to in the editor rather than being pinned here.
 * Change the widget's Row Gap and both axes move together.
 *
 * Written as a custom property rather than a `column-gap` declaration: the rule
 * that would have to be beaten is `.elementor-widget-loop-grid .elementor-grid`,
 * two classes, and it reads `var(--grid-column-gap, 30px)`. Supplying the
 * variable is what that rule is asking for; out-specifying it would be a fight
 * that a later Elementor release could win back.
 */
.elementor-widget-loop-grid {
  --grid-column-gap: var(--grid-row-gap, 24px);
}

/*
 * Headings inherit their line-height, as they did before Hello Elementor.
 *
 * Hello's reset.css sets `h1, h2, h3, h4, h5, h6 { line-height: 1.2 }`. The
 * retired theme had no such rule, so a heading that did not name a line-height
 * inherited the body's 1.7 — and most of the design's heading rules do not name
 * one. Card titles came out at 21.6px of leading where the design has 30.6px,
 * on every card on the site.
 *
 * Deliberately one class and one element (0,1,1): enough to beat Hello's bare
 * element selector, not enough to beat a design rule that does set a
 * line-height — those are doubled in typography-fix.css and still win.
 */
.elementor h1,
.elementor h2,
.elementor h3,
.elementor h4,
.elementor h5,
.elementor h6 {
  line-height: inherit;
}

/*
 * The industry filter bar.
 *
 * The design styles its own markup — a labelled bar of `__filter-btn` pills
 * with `__filter-btn-active` on the current one. Elementor's Taxonomy Filter
 * generates its own instead: `<search class="e-filter">` holding
 * `<button class="e-filter-item" aria-pressed>`. None of the design's classes
 * can be put on those buttons, so the bar rendered as a row of plain text
 * links.
 *
 * These are the design's own declarations, pointed at the markup Elementor
 * actually produces. The active state comes from `aria-pressed`, which
 * Elementor already maintains — reading the accessible state rather than a
 * second class means the two cannot disagree.
 */
.np-industry-filter__filters {
  background: var(--light);
  border-bottom: 1px solid var(--rule);
  padding: 18px 40px;
}

.np-industry-filter__filters .e-filter {
  max-width: var(--container-width);
  margin: 0 auto;
  display: flex;
  align-items: center;
  /* Elementor's alignment control defaults to centred; the design starts left. */
  justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
}

/* The label the design puts before the pills; Elementor's widget has no slot
   for one, so it is drawn here. Elementor gives "All" `order: -1` to pull it
   ahead of the terms, which also pulled it ahead of this label. */
.np-industry-filter__filters .e-filter::before {
  order: -2;
  content: "Filter by industry:";
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 4px;
}

.np-industry-filter__filters .e-filter-item {
  font-size: 13px;
  font-weight: 400;
  padding: 6px 16px;
  border-radius: 100px;
  border: 1px solid var(--rule);
  background: #fff;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.2s;
}

.np-industry-filter__filters .e-filter-item[aria-pressed="true"] {
  background: var(--green2);
  color: #fff;
  border-color: var(--green2);
}

/* ------------------------------------------------------------------ *
 * The header sticks to the top of the viewport.
 *
 * `.np-header__nav` already says `position: sticky; top: 0` — the design's own
 * declaration — and it never stuck, because Elementor wraps the header
 * template in `<header class="elementor-location-header">` and a sticky
 * element only travels inside its parent's box. That wrapper is exactly as
 * tall as the bar it holds, so the bar had nowhere to go and scrolled away
 * with the page.
 *
 * The wrapper is the element that has the page to travel through, so the
 * stickiness belongs on it. The inner rule stays: it is the design's, it is
 * harmless nested inside a sticky parent, and it is what a reader of
 * header.css expects to find.
 * ------------------------------------------------------------------ */
.elementor-location-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

/* ------------------------------------------------------------------ *
 * Links the design draws itself, built from Elementor's Button widget.
 *
 * `_css_classes` lands on the widget's wrapper <div>, never on the <a> inside
 * it. So the design's button is drawn on the wrapper — and Elementor's own
 * button skin, a coloured ground with 12px/24px of padding and a 3px radius,
 * is still drawn on the anchor within it. That is the box inside a box on the
 * hero's two calls to action, and a filled pill where the design has a plain
 * green text link ("View all case studies", "Read the full story").
 *
 * Elementor's button widget has no control for a class on the anchor, so the
 * split cannot be fixed where the templates are built. The wrapper keeps the
 * design's rules; the anchor is stripped back to text and stretched over the
 * wrapper, which also makes the whole shape a click target rather than just
 * the words inside it.
 *
 * The hero's np-button variants are deliberately excluded: button.css now
 * applies their legacy filled/outlined shape to the actual anchor. Listed one
 * by one rather than matched on a prefix so a button an editor adds in
 * Elementor still looks like an Elementor button.
 * ------------------------------------------------------------------ */
.np-button__btn,
.np-about-teaser__link,
.np-about__closing-cta,
.np-case-studies-preview__view-all,
.np-news-preview__view-all,
.np-contact-section__cta,
.np-featured-news-card__button {
  position: relative;
}

/*
 * Three classes deep, and `:is()` rather than one selector per link.
 *
 * Elementor prints its own `.elementor-widget-button .elementor-button` and
 * `.elementor-widget-loop-grid .elementor-button` for the kit's accent colour,
 * both two classes and both after this file. A two-class reset tied and lost
 * on source order, which is why the featured news card kept an orange button
 * inside its green one after the hero's had already come right.
 */
.elementor-widget-button:is(
    .np-about-teaser__link,
    .np-about__closing-cta,
    .np-case-studies-preview__view-all,
    .np-news-preview__view-all,
    .np-contact-section__cta,
    .np-featured-news-card__button
  ) .elementor-button,
.elementor-widget-button:is(
    .np-about-teaser__link,
    .np-about__closing-cta,
    .np-case-studies-preview__view-all,
    .np-news-preview__view-all,
    .np-contact-section__cta,
    .np-featured-news-card__button
  ) .elementor-button:is(:hover, :focus, :visited) {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  color: inherit;
  fill: currentColor;
  font: inherit;
  letter-spacing: inherit;
  text-align: inherit;
  transition: none;
}

/*
 * A design button shrinks to its content.
 *
 * The design's button is an `inline-flex` anchor that shrink-wraps inside
 * whatever block holds it. Elementor's wrapper is a block-level flex item, and
 * `align-items: stretch` on the container blockifies it and pulls it to the
 * full width — so the home page's "Contact Us" rendered as an orange bar the
 * width of the band with its label at the left, instead of a centred button.
 *
 * The cross-axis value follows the design: the contact band centres its column,
 * the about teaser's link sits at the left of its. Buttons in a flex *row* —
 * the hero pair, the two "view all" links, the featured news card — already
 * shrink-wrap on the main axis and are left out.
 */
.np-contact-section__cta {
  align-self: center;
}

.np-about-teaser__link {
  align-self: flex-start;
}

/* The anchor covers the wrapper, so the design's padding is clickable too. */
.elementor-widget-button:is(
    .np-about-teaser__link,
    .np-about__closing-cta,
    .np-case-studies-preview__view-all,
    .np-news-preview__view-all,
    .np-contact-section__cta,
    .np-featured-news-card__button
  ) .elementor-button::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* ------------------------------------------------------------------ *
 * Badges and section headings drawn with Elementor's Heading widget.
 *
 * The same split as the buttons above: the design class lands on the widget's
 * wrapper, and Elementor's kit colours the `.elementor-heading-title` inside
 * it — two classes, printed after this file. So a badge whose design says
 * `color: white` on a green ground rendered in the kit's dark navy, which is
 * what made the industry and date labels on the news cards read as black.
 *
 * The title takes the wrapper's own typography, which is where the design puts
 * it. Only the classes that actually set type or colour on themselves are
 * listed: a heading styled through a descendant rule instead — the two hero
 * titles, the card titles under `np-card-stretch` — must keep inheriting
 * nothing, or this would outrank the rule that styles it.
 * ------------------------------------------------------------------ */
.elementor-widget-heading:is(
    .np-about-teaser__heading,
    .np-case-studies-preview__heading,
    .np-case-studies-preview__tag,
    .np-case-study-card__tag,
    .np-featured-news-card__tag,
    .np-how-to-guide-card__tag,
    .np-news-article__tag,
    .np-news-article__title,
    .np-news-card__date,
    .np-news-card__tag,
    .np-news-preview__heading,
    .np-news__section-eyebrow,
    .np-page-header__eyebrow,
    .np-process-section__heading,
    .np-product-card__tag,
    .np-testimonials__heading,
    .np-video-preview__heading,
    .np-why-section__heading
  ) .elementor-heading-title {
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  font-style: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  text-transform: inherit;
}

/* ------------------------------------------------------------------ *
 * Card thumbnails.
 *
 * `.np-fill` is the design's stand-in for next/image's `fill`, and on a card
 * it is set through `_css_classes` — so it lands on the image widget's wrapper
 * and the <img> inside keeps `height: auto`. A portrait photograph therefore
 * rendered at its full height, out of the 180px window the card gives it and
 * straight over the title and excerpt below. The design's own `object-fit`
 * classes (`__thumbnail`, `__cover`, `__card-image`) land on that same wrapper
 * and so never reached an image either.
 *
 * A bare `.np-fill` on an <img> — which is what the NanoPrep widgets emit —
 * does not match this and is unaffected.
 * ------------------------------------------------------------------ */
.np-fill img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ------------------------------------------------------------------ *
 * Card badges sit above the thumbnail.
 *
 * Both the badge and the `.np-fill` image wrapper are absolutely positioned
 * with no stacking order of their own, so which one is drawn on top comes down
 * to document order — and the loop-item builder emits the badge first. Every
 * industry, category and date label was painted over by its own photograph.
 *
 * Above the stretched link below as well, at 2, so the industry term stays a
 * link of its own.
 * ------------------------------------------------------------------ */
.np-case-study-card__tag,
.np-case-studies-preview__tag,
.np-how-to-guide-card__tag,
.np-news-card__tag,
.np-news-card__date,
.np-product-card__tag {
  z-index: 2;
}

/* ------------------------------------------------------------------ *
 * The whole card is a click target.
 *
 * The design's card is one <a> around the image, the badge, the title, the
 * excerpt and the "Read case study" line. A Loop Grid cannot reproduce that —
 * a container's dynamic link resolves once per document rather than once per
 * item — so the link lives on the title, which does resolve per post, and the
 * title's anchor is stretched over the card.
 *
 * That was written for the case studies archive card only. The other four
 * cards carry the same `np-card-stretch` title and got no rule, so on the home
 * page, the news page and the how-to library everything but the heading itself
 * was dead to a click — including the "Read case study" line, which is text
 * rather than a link in every one of these cards.
 *
 * And on the archive card, where the rule did exist, it stretched over nothing
 * but the heading. `inset: 0` resolves against the nearest positioned
 * ancestor, and Elementor positions both of the elements in between: every
 * widget is `.elementor-widget { position: relative }` and every container is
 * `.e-con { position: relative }`. So the overlay measured itself against the
 * title widget — 53px of it — and the card below stayed unclickable.
 *
 * Returning the title widget and the card body to `static` hands the overlay
 * up to the card, which the design and Elementor both already position. Both
 * hold ordinary flowed widgets and neither is a containing block for anything
 * else; the image wrapper, which is one — it holds the badge — stays relative.
 * ------------------------------------------------------------------ */
.np-card-stretch,
.np-case-study-card__body,
.np-case-studies-preview__content,
.np-how-to-guide-card__content,
.np-news-card__content,
.np-product-card__body {
  position: static;
}

.np-card-stretch a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* ------------------------------------------------------------------ *
 * Every card in a row is the same height.
 *
 * The Loop Grid already stretches its cells — the `[data-elementor-type]`
 * wrapper around each item takes the height of the tallest card in the row —
 * but the card inside it is a container that sizes to its own content, so a
 * short summary left a card floating in a taller cell with a strip of the
 * section's background showing beneath it.
 *
 * Handing the wrapper's height down to the card is all that is needed; the
 * summaries themselves are clamped in each card's own stylesheet, so a long
 * one no longer sets the height for the whole row.
 * ------------------------------------------------------------------ */
.elementor-loop-container > [data-elementor-type="loop-item"] {
  display: flex;
  flex-direction: column;
}

.elementor-loop-container > [data-elementor-type="loop-item"] > .e-con {
  flex: 1;
}

/* ------------------------------------------------------------------ *
 * A converted post body flows like a document again.
 *
 * `convert-bodies.php` turns each block of an article into its own Elementor
 * widget, and Elementor stacks those widgets in a flex container with a 20px
 * gap. Two things follow, and both are visible on every case study and product
 * page:
 *
 *   - The gap is added to the design's own margins rather than replacing them,
 *     so every space in the article came out 20px too wide.
 *   - Margins do not collapse between flex items. The design's rhythm — 32px
 *     above a heading, 12px below it, 14px after a paragraph — is written as
 *     margins on the blocks themselves and relies on adjacent ones collapsing
 *     to the larger of the two.
 *
 * Laying the container out as a block puts both back: the widget wrappers have
 * no padding or border of their own, so each block's margin collapses straight
 * through its wrapper and meets its neighbour's exactly as it did in the
 * original markup.
 *
 * The heading rules are then restated against the structure the conversion
 * produces. Every heading is the only child of its own widget, so the design's
 * `h2:first-child { margin-top: 0 }` matched all of them and flattened the
 * space above every section title in the article; first-child now means the
 * first widget in the body, which is what it meant before the conversion.
 * ------------------------------------------------------------------ */
.np-article-blocks__article [data-elementor-type="wp-post"] > .e-con,
.np-content-blocks__content [data-elementor-type="wp-post"] > .e-con {
  display: block;
}

.np-article-blocks__article .elementor-widget h2 {
  margin-top: 32px;
}

/*
 * Both margins, because the rules further up this file that set them use a
 * child combinator (`.np-content-blocks__content > h2`) and were written for
 * core blocks sitting directly in the wrapper. After the conversion each block
 * is inside a widget, so none of them reach an h2 any more.
 */
.np-content-blocks__content .elementor-widget h2 {
  margin: 36px 0 14px;
}

/*
 * "First" means the first block of the body, not the first child of any widget.
 *
 * The whole converted body sits inside a Post Content widget, which *is* a
 * first child — so a loose `.elementor-widget:first-child h2` matched every
 * heading in the article through that ancestor and zeroed the space above all
 * of them, which is the bug this section exists to fix.
 */
.np-article-blocks__article [data-elementor-type="wp-post"] > .e-con > .elementor-widget:first-child h2,
.np-content-blocks__content [data-elementor-type="wp-post"] > .e-con > .elementor-widget:first-child h2 {
  margin-top: 0;
}

/* ------------------------------------------------------------------ *
 * The guide's two columns.
 *
 * `np-apply-nanoprep__wrap` is a boxed container, so its only child is the
 * `.e-con-inner` Elementor centres inside it — and the design's grid was
 * therefore laying out that one element rather than the article and the
 * sidebar. The inner element took the first track and the two columns were
 * flexed inside it at whatever width was left, which is why the guide sat
 * hard against the left edge in a column narrower than the design's.
 *
 * The layout moves to the element that actually holds the two columns. The
 * outer keeps the vertical inset; Elementor already centres the inner one and
 * caps it at the container width, so the design's `max-width` and `margin`
 * would only restate what is there.
 * ------------------------------------------------------------------ */
.np-apply-nanoprep__wrap {
  display: block;
}

.np-apply-nanoprep__wrap > .e-con-inner {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 60px;
  align-items: start;

  /*
   * The inset goes here too, for the same reason as the case study body: the
   * 40px is inside the 1200px column, not outside it. Padding the outer
   * element would leave the columns 80px wider than the design's 760 and 300.
   */
  padding: 64px 40px 32px;
}

@media (max-width: 900px) {
  .np-apply-nanoprep__wrap > .e-con-inner {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

/*
 * The browser's own 40px indent on a <dd>.
 *
 * The retired theme opened with a blanket margin reset that every converted
 * stylesheet was written on top of, and the "at a glance" list is one of the
 * places that assumed it: the design draws the label above its value, flush
 * left. Hello Elementor resets less, so each value sat indented under its
 * label. The list elements already have their reset near the top of this file;
 * a description list needs the same.
 */
[class^="np-"] dd,
[class*=" np-"] dd {
  margin-inline-start: 0;
}

/*
 * The guide's opening paragraphs.
 *
 * They are two text widgets in a flex column, so the design's own 14px and
 * 40px would be added to Elementor's 20px gap rather than replacing it, and
 * their bottom margins would be zeroed by the widget rule described above.
 * Dropping the gap and restating the margins one class stronger puts the
 * design's spacing back exactly.
 */
.np-apply-nanoprep__main {
  --row-gap: 0px;
}

.np-apply-nanoprep__main .elementor-widget.np-apply-nanoprep__intro {
  margin-bottom: 14px;
}

.np-apply-nanoprep__main .elementor-widget.np-apply-nanoprep__intro-sub {
  margin-bottom: 40px;
}

/*
 * The news article header band.
 *
 * Its three parts are widgets in a flex column, so Elementor's 20px gap was
 * added to the design's own 16px margins rather than replacing them, and the
 * tag's bottom margin was zeroed by the widget rule described further up. The
 * band came out 23px taller than the design with the spacing in the wrong
 * proportions.
 */
.np-news-article__header-inner {
  --row-gap: 0px;
}

.np-news-article__header-inner .elementor-widget.np-news-article__tag {
  margin-bottom: 16px;
  /* The design's pill is inline-block; as a flex item it stretched full width. */
  align-self: flex-start;
}

/* ------------------------------------------------------------------ *
 * A design width on a widget.
 *
 * Elementor caps every widget in a container at the container's width —
 * `.e-con.e-con>.e-con-inner>.elementor-widget, .elementor.elementor
 * .e-con>.elementor-widget { max-width: 100% }`, four classes — and several of
 * the design's standfirsts are one class saying `max-width: 560px`. Elementor
 * won every one of them, so the sentence under a page title or a section
 * heading ran the full width of the band instead of wrapping in the column the
 * design gives it. It is only visible on a wide window, which is why it read as
 * "the text is not the same" rather than as a missing rule.
 *
 * Five classes, so nothing has to rely on which stylesheet is printed last.
 * Listed explicitly: a blanket `max-width: none` for anything NanoPrep-classed
 * would remove the cap that stops a widget overflowing its container.
 * ------------------------------------------------------------------ */
.elementor.elementor .e-con > .elementor-widget:is(.np-page-header__sub, .np-video-preview__sub),
.elementor.elementor .e-con > .e-con-inner > .elementor-widget:is(.np-page-header__sub, .np-video-preview__sub) {
  max-width: 560px;
}

/* The home hero's standfirst is 520px in home-hero.css. */
.elementor.elementor .e-con > .elementor-widget.np-home-hero__sub,
.elementor.elementor .e-con > .e-con-inner > .elementor-widget.np-home-hero__sub {
  max-width: 520px;
}

/* The news headline is 840px in news-article.css. */
.elementor.elementor .e-con > .elementor-widget.np-news-article__title,
.elementor.elementor .e-con > .e-con-inner > .elementor-widget.np-news-article__title {
  max-width: 840px;
}

/* ------------------------------------------------------------------ *
 * The "Aus | Made" badge.
 *
 * The design stacks the two spans as flex items of the circle, and Elementor
 * prints them directly inside the widget. What pulled them apart is a gap the
 * design never had: Elementor gives every widget `gap: var(--row-gap)`, and
 * the badge inherits the surrounding container's 20px `--row-gap`. As a flex
 * column that put 20px between "Aus" and "MADE" (measured on the live page).
 * The gap is zeroed, each span keeps the line height it has in the legacy
 * theme — 1 for "Aus", the body's 1.7 for "MADE" — and the circle restates
 * its centring. Any wrapper Elementor may add (the legacy widget container, or
 * a <p> from an editor's save) collapses into the same column.
 * ------------------------------------------------------------------ */
.elementor.elementor .e-con .elementor-widget.np-about-teaser__badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  color: #fff;
  line-height: 1;
}

.elementor.elementor .e-con .elementor-widget.np-about-teaser__badge :is(.elementor-widget-container, .elementor-text-editor, p) {
  display: contents;
}

.elementor.elementor .e-con .elementor-widget.np-about-teaser__badge span {
  display: block;
  margin: 0;
  color: inherit;
  line-height: 1;
}

.elementor.elementor .e-con .elementor-widget.np-about-teaser__badge span:last-child {
  line-height: 1.7;
}

/* ------------------------------------------------------------------ *
 * Footer link columns.
 *
 * They are Nav Menu widgets, whose typography defaults to the kit's Primary
 * font — Barlow Condensed, the heading face. The design's footer links are
 * body text (`.np-footer__col ul a` sets no family). Four classes: stronger
 * than Elementor's global default (three), weaker than a font an editor sets
 * on the widget itself (five), so the widget's own control still wins.
 * ------------------------------------------------------------------ */
.elementor .np-footer__col .elementor-nav-menu .elementor-item {
  font-family: var(--font-body);
  letter-spacing: normal;
  text-transform: none;
  line-height: 1.7;
}

/* ------------------------------------------------------------------ *
 * The news article body.
 *
 * `np-news-article__content-wrap` is a boxed container, and Elementor centres
 * a 1200px `.e-con-inner` inside it — which is why the article read at full
 * width instead of in the design's 900px column. As in case-study.css, the
 * column and its padding go on the inner element, and the outer one is left
 * unpadded so the two do not add up. The container's 20px gap is replaced by
 * the design's own spacing: the lead's 28px, the back link's 30px.
 * ------------------------------------------------------------------ */
.elementor .e-con.np-news-article__content-wrap {
  padding: 0;
  --row-gap: 0px;
}

.e-con.np-news-article__content-wrap > .e-con-inner {
  max-width: 900px;
  margin: 0 auto;
  padding: 52px 40px;
}

/* The excerpt as the lead: the Post Excerpt widget prints bare text. */
.elementor .e-con .elementor-widget.np-news-article__lead {
  margin-bottom: 28px;
  font-size: 18px;
  line-height: 1.75;
  color: var(--text);
  font-weight: 400;
}

.elementor .e-con .elementor-widget.np-news-article__lead > * {
  font: inherit;
  color: inherit;
}

/* Technical Resources: the design's 1100px column (its `__inner` wrapper),
   applied to the 1200px `.e-con-inner` Elementor centres in the boxed section. */
.e-con.np-technical-resources__section > .e-con-inner {
  max-width: 1100px;
}

/* ------------------------------------------------------------------ *
 * The page header with a photograph behind it.
 *
 * Two things the design writes as plain declarations, which an Elementor
 * container expresses differently:
 *
 *   height          `.np-page-header__header-photo` is `height: 600px` and
 *                   `min-height: 600px`, and the About page overrides both to
 *                   300 — the retired template did that with an inline style.
 *                   Elementor has no height control on a container, only Min
 *                   Height, and it sets that through `--min-height` on a rule
 *                   the design's own `min-height` outranks. So the band kept
 *                   the 600px default and the About banner rendered at twice
 *                   the height the design gives it. Reading the variable here
 *                   is what puts the page in charge of the height, and puts the
 *                   number in the editor; the design's 600 stays the default
 *                   for a header that does not set one.
 *
 *   alignment       `align-items: flex-end` bottom-aligns the contents of a
 *                   *row*, which is what the original markup was. An Elementor
 *                   container is a column, where the same declaration means
 *                   "against the right edge" — so the breadcrumb, title and
 *                   standfirst sat at the top of the band rather than at the
 *                   foot of it. `justify-content` is the column axis.
 *
 * Only the About page has a photograph in its header; every other page header
 * is the flat gradient band and is untouched by this.
 * ------------------------------------------------------------------ */
.np-page-header__header-photo {
  height: auto;
  min-height: var(--min-height, 600px);
  justify-content: flex-end;
}

/*
 * The header's four parts stack with the design's own spacing.
 *
 * They are widgets in a flex column, so Elementor's 20px gap was added between
 * each of them — 60px of space the design does not have, on every page header
 * on the site. It is what pushed the About banner's content past the 300px the
 * band is given even after the height came right.
 *
 * The trail and the title carry their margins on elements inside their widgets
 * and are unaffected. The eyebrow's is on the widget itself, where Elementor
 * zeroes it with `.e-con .elementor-widget.elementor-widget`, so it is restated
 * one class stronger.
 */
.np-page-header__inner {
  --row-gap: 0px;
}

.np-page-header__inner .elementor-widget.np-page-header__eyebrow {
  margin-bottom: 12px;
}

/* ------------------------------------------------------------------ *
 * The two forms, focused.
 *
 * Everything else the design says about them is set through the Form widget's
 * own Style controls — see np_el_form() in
 * wordpress/tools/migration/elementor-forms.php — so that an editor can change
 * it. The focus ring is the exception: Pro has no control for it, and its own
 * `.elementor-field-group .elementor-field-textual:focus` draws a grey inset
 * shadow over both designs. It is the one piece of feedback a keyboard user
 * gets while filling a form in, so it is worth the two rules.
 * ------------------------------------------------------------------ */
.elementor .np-contact-form__form .elementor-field-group .elementor-field-textual:focus {
  border-color: var(--green2);
  box-shadow: 0 0 0 3px rgba(58, 170, 106, 0.15);
}

/* The panel's is a border colour and nothing else. */
.elementor .np-contact-panel__form .elementor-field-group .elementor-field-textual:focus {
  border-color: var(--green);
  box-shadow: none;
}

/* ------------------------------------------------------------------ *
 * The line that closes the About page.
 *
 * The design gives its `h3` `flex: 1; min-width: 260px` — the mark and the
 * button take the space they need and the sentence takes the rest. In Elementor
 * the h3 is inside a widget, and the widget is the flex item: it sized itself
 * to the whole sentence, the three came to more than the row is wide, and
 * because the row wraps rather than shrinks the button dropped onto a line of
 * its own under the mark.
 *
 * The design's rule, moved onto the element that is actually the flex item.
 * ------------------------------------------------------------------ */
.np-about__closing-panel > .elementor-widget-heading {
  flex: 1;
  min-width: 260px;
}

/* ------------------------------------------------------------------ *
 * The case study specification table.
 *
 * Hello Elementor's reset.css styles bare `<table>` markup, and three of its
 * rules are written strongly enough to outrank the design's own:
 *
 *   table tbody > tr:nth-child(odd) > td   (0,1,3)  grey zebra striping
 *   table tbody tr:hover > td              (0,1,3)  a hover highlight
 *   table td, table th                     (0,0,3)  a grey border on all four
 *                                                   sides, and line-height 1.5
 *   table thead:first-child tr:first-child th
 *                                          (0,2,4)  a border above the header
 *
 * The design's rules in article-blocks.css are single-class (0,1,2): they win
 * the padding and the colours, and lose the striping and the borders. The
 * "Project Specification" table therefore rendered as banded grey rows inside a
 * grid of grey cell borders, where the design is white rows separated by a
 * single rule in `--rule`.
 *
 * Three classes rather than two, because two ties with the `thead:first-child`
 * selector above and loses on element count. The background is reset on `tbody`
 * only — the header row's navy is the design's and must survive.
 * ------------------------------------------------------------------ */
.np-article-blocks__spec-table.np-article-blocks__spec-table.np-article-blocks__spec-table td,
.np-article-blocks__spec-table.np-article-blocks__spec-table.np-article-blocks__spec-table th {
  border: 0;
  line-height: inherit;
}

.np-article-blocks__spec-table.np-article-blocks__spec-table.np-article-blocks__spec-table tbody td {
  background-color: transparent;
}

/* The design's one rule between rows, restored above the blanket reset. */
.np-article-blocks__spec-table.np-article-blocks__spec-table.np-article-blocks__spec-table tbody tr:not(:last-child) td {
  border-bottom: 1px solid var(--rule);
}

/* ------------------------------------------------------------------ *
 * `.np-fill` images fill their frame again.
 *
 * `.np-fill` is the design's stand-in for next/image's `fill`: the image is
 * absolutely positioned and *is* its container, so the container decides the
 * shape and `object-fit` decides how the photograph sits inside it. Every
 * photograph the NanoPrep widgets place works that way -- case study and
 * product heroes, page banners, card thumbnails, and the article galleries.
 *
 * Elementor's own `.elementor img { height: auto }` is (0,1,1) and `.np-fill`
 * is (0,1,0), so the height lost and every one of those images laid itself out
 * at its natural aspect instead. `object-fit` then had nothing to do -- an
 * element already at its natural aspect is already "fitted" -- and whatever
 * overflowed the frame was either cropped by `overflow: hidden` or simply left
 * hanging out of it. Two ways that showed:
 *
 *   heroes      the water tank hero band is 386px tall and its photograph came
 *               out 607px, so the band showed the top of the image rather than
 *               the centred crop `cover` was asked for.
 *   galleries   a 1200x1600 photograph in a 1200x900 frame stayed 1200x1600
 *               and lost its bottom 700px, where the design letterboxes it.
 *
 * Invisible wherever the photograph's shape happens to match its frame, which
 * is most of the 4:3 landscape ones -- which is why this read as a handful of
 * unrelated "this image looks wrong" pages rather than as one rule being lost.
 *
 * Matched on `img.np-fill` so it reaches only the bare class on an <img>, which
 * is what the widgets emit. The card thumbnails set `.np-fill` through
 * `_css_classes`, which lands it on the image widget's wrapper instead; those
 * are a `div` and are served by the `.np-fill img` rule further up.
 * ------------------------------------------------------------------ */
.elementor img.np-fill {
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------------ *
 * The About page's two marks.
 *
 * The Belzona badge is capped in the design — `.np-about__intro-badge img`
 * gives it `max-width: 220px` — and Elementor's image widget carries
 * `.elementor-widget-image img { max-width: 100% }`. Two classes beats one
 * class and an element, so the cap never applied and a 1897px logo filled its
 * column at 391px, nearly twice the size the design draws it.
 *
 * The NanoPrep mark in the closing panel has no rule to lose: the design never
 * needed one, because the markup asked for the image at 160px and the file is
 * a 320px retina copy. An Elementor image widget renders the attachment at its
 * own size instead, so the mark came out at 320 — the same doubling, arrived at
 * from the other direction.
 *
 * Both are stated here rather than in about.css because both are corrections to
 * Elementor's defaults rather than design values, and the first has to outrank
 * a two-class selector to take effect at all.
 * ------------------------------------------------------------------ */
.np-about__intro-badge.np-about__intro-badge img {
  width: 100%;
  max-width: 220px;
  height: auto;
}

.np-about__closing-panel.np-about__closing-panel img {
  width: 160px;
  max-width: 100%;
  height: auto;
}

/* ------------------------------------------------------------------ *
 * The hero headline carries no margin of its own.
 *
 * The design never says so, because the retired theme opened with a blanket
 * margin reset that every converted stylesheet was written on top of. Hello
 * Elementor resets less, so the hero's h1 kept the browser's margins — 8px
 * above and 16px below — and pushed the band 24px taller than the design draws
 * it. Same omission as the `<dd>` indent further up this file.
 * ------------------------------------------------------------------ */
.np-detail-hero__content h1,
.np-page-header__inner h1 {
  margin: 0;
}

/* ------------------------------------------------------------------ *
 * An article body spaces itself by its own margins.
 *
 * The converted bodies are a column of Elementor widgets, and an Elementor
 * container is a flex column with a 20px gap. The design's stylesheets were
 * written for the retired theme's block layout, where a heading's 32px above
 * and a paragraph's 14px below decide the rhythm on their own — so every one of
 * those margins had 20px added to it. Small per gap, and the page drifts: the
 * "Key benefits" heading on the NanoPrep product sat 150px lower than the
 * design draws it, with everything below pushed down to match.
 *
 * Only inside the design's own body wrappers. An Elementor container's gap is
 * the right default everywhere an editor builds a layout from widgets; it is
 * wrong only where the content already carries the spacing, which is exactly
 * what these two classes mark.
 *
 * Measured against the legacy build: heading-to-paragraph 34px -> 14px, and
 * paragraph-to-paragraph 36px -> 16px, which are the design's own values.
 * ------------------------------------------------------------------ */
.np-content-blocks__content .e-con,
.np-content-blocks__content .e-con-inner,
.np-article-blocks__article .e-con,
.np-article-blocks__article .e-con-inner {
  --row-gap: 0px;
  row-gap: 0px;
}

/* ------------------------------------------------------------------ *
 * The standalone breadcrumb bar keeps to the content column.
 *
 * `.np-breadcrumbs__inner` is centred at the container width, so the trail
 * begins where the article does. The list reset near the top of child.css —
 * `[class^="np-"] ol { margin: 0 }` — is a class and an element, and the
 * design's rule is a class alone, so the reset won and `margin: 0 auto` never
 * applied: the trail sat at the bar's 40px padding instead of the 120px where
 * the column starts, 80px left of everything below it.
 * ------------------------------------------------------------------ */
.np-breadcrumbs__inner.np-breadcrumbs__inner {
  max-width: var(--container-width);
  margin-inline: auto;
}
