/* ==========================================================================
   NTM — WordPress shim
   --------------------------------------------------------------------------
   Everything WordPress and Contact Form 7 need in order to sit inside the
   prototype's design. css/style.css stays untouched so it can be diffed
   against the static original at any time.

   Loads after style.css. Uses the same relative asset root (../assets/).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset corrections
   -------------------------------------------------------------------------- */

/* A .foo { display:flex } rule loading later beats [hidden] on specificity. */
[hidden] { display: none !important; }

/* Accessible skip link — visible only on keyboard focus. */
.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip-link:focus {
  position: fixed !important;
  top: 8px; left: 8px;
  z-index: 100000;
  width: auto; height: auto;
  margin: 0; padding: 12px 20px;
  clip: auto; clip-path: none;
  background: var(--gold);
  color: var(--ink);
  font-family: var(--cond);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}

/* --------------------------------------------------------------------------
   2. Admin bar — the masthead is position:sticky; top:0
   -------------------------------------------------------------------------- */
body.admin-bar .site-header { top: 32px; }
@media screen and (max-width: 782px) {
  body.admin-bar .site-header { top: 46px; }
}

/* --------------------------------------------------------------------------
   3. Editor-supplied background images
   --------------------------------------------------------------------------
   style.css already drives .page-hero from a --hero-bg custom property, so an
   editor-picked image only needs the property set inline. These rules add the
   same gradient stack for heroes with no preset variant, and extend the same
   pattern to the two figures that are otherwise CSS-only.
   -------------------------------------------------------------------------- */

.page-hero--custom {
  background-color: var(--ink);
  background-blend-mode: normal;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(100deg,
      rgba(8,16,20,.97) 0%,
      rgba(8,16,20,.94) 30%,
      rgba(8,16,20,.82) 50%,
      rgba(8,16,20,.45) 78%,
      rgba(10,90,120,.55) 100%),
    var(--hero-bg, url('../assets/images/dark-shop-floor.jpg'));
}

.intro-figure .blueprint {
  background:
    linear-gradient(135deg, rgba(8,16,20,.55), rgba(8,16,20,.25) 50%, rgba(10,90,120,.4)),
    var(--fig-img, url('../assets/images/dark-shop-floor.jpg')) center/cover var(--ink);
}

.legacy-figure {
  background:
    linear-gradient(115deg, rgba(8,16,20,.86), rgba(8,16,20,.72) 55%, rgba(6,30,40,.88)),
    var(--legacy-img, url('../assets/images/vintage-and-cnc.jpg')) center/cover var(--ink);
}

/* --------------------------------------------------------------------------
   4. Contact Form 7
   --------------------------------------------------------------------------
   CF7's own stylesheet is dequeued so its colours don't fight the design, so
   the structural rules it would otherwise supply are reproduced here. Without
   them the hidden-fields <fieldset> draws a browser-default border and the
   screen-reader response block renders as visible empty space.

   4a. Structural — port of includes/css/styles.css
   -------------------------------------------------------------------------- */

.wpcf7 .screen-reader-response {
  position: absolute;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  word-wrap: normal !important;
  word-break: normal !important;
}

.wpcf7 .hidden-fields-container { display: none; }

.wpcf7-form-control-wrap { position: relative; }

.wpcf7 [inert] { opacity: .5; }
.wpcf7 input[type="file"] { cursor: pointer; }
.wpcf7 input[type="file"]:disabled { cursor: default; }
.wpcf7 button:disabled,
.wpcf7 .wpcf7-submit:disabled { cursor: not-allowed; opacity: .6; }
.wpcf7 input[type="url"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"] { direction: ltr; }

.wpcf7-list-item { display: inline-block; margin: 0 0 0 1em; }
.wpcf7-list-item-label::before,
.wpcf7-list-item-label::after { content: " "; }

.wpcf7-reflection > output { display: list-item; list-style: none; }
.wpcf7-reflection > output[hidden] { display: none; }

/* Spinner, restyled in the site's gold rather than CF7's grey. */
.wpcf7-spinner {
  visibility: hidden;
  display: inline-block;
  width: 20px;
  height: 20px;
  padding: 0;
  margin: 0 0 0 12px;
  border: 2px solid rgba(255, 211, 70, .25);
  border-top-color: var(--gold);
  border-radius: 50%;
  vertical-align: middle;
  animation: ntm-spin 800ms linear infinite;
}
.wpcf7 form.submitting .wpcf7-spinner { visibility: visible; }

@keyframes ntm-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .wpcf7-spinner { animation: ntm-blink 1600ms ease-in-out infinite; }
  @keyframes ntm-blink { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
}

/* --------------------------------------------------------------------------
   4b. Visual — CF7's markup wearing the prototype's clothes
   --------------------------------------------------------------------------
   Each control arrives wrapped in <span class="wpcf7-form-control-wrap">,
   which is inline by default and would collapse the .field layout. CF7's
   validation classes are mapped onto the .field.invalid / .err treatment.
   -------------------------------------------------------------------------- */

.wpcf7 form .wpcf7-response-output {
  margin: 14px 0 0;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-family: var(--mono);
  font-size: .72rem;
  line-height: 1.5;
  border: 1px solid var(--steel-700);
  color: var(--steel-300);
}
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.payment-required .wpcf7-response-output {
  border-color: #ff7a6b;
  color: #ff9d92;
}
.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output {
  border-color: #ff7a6b;
  color: #ff9d92;
}
.wpcf7 form.sent .wpcf7-response-output,
.wpcf7 form.init .wpcf7-response-output,
.wpcf7 form.resetting .wpcf7-response-output,
.wpcf7 form.submitting .wpcf7-response-output { display: none; }

.field .wpcf7-form-control-wrap { display: block; }

/* Contact Form 7 writes the error text itself, so .wpcf7-not-valid-tip takes
   over the role the prototype's .err span had — same position, same styling.
   The two must never both appear, which is why the CF7 form template carries
   no .err spans at all. */
.field .wpcf7-not-valid-tip {
  display: block;
  font-family: var(--mono);
  font-size: .68rem;
  color: #ff9d92;
  margin-top: 5px;
}
.field .wpcf7-not-valid {
  border-color: #ff7a6b;
}

/* Deliberate deviation from the prototype.
   In style.css, `.form-card .field input` (0-2-1) is declared after
   `.field.invalid input` (0-2-1), so on the light contact card an errored
   field kept its normal grey border — an error state with no visual change.
   This restores it, in a red with enough contrast against --paper-warm to
   satisfy WCAG 1.4.11 non-text contrast. Delete this block to go back to the
   prototype's exact behaviour. */
.form-card .field .wpcf7-not-valid {
  border-color: #e05a4a;
}

/* Submit button: CF7 renders <input type="submit">, the prototype styles a
   <button>. The form template uses a <button>, so this only covers the
   spinner CF7 injects next to it. */
.wpcf7-spinner {
  margin: 0 0 0 10px;
  vertical-align: middle;
}
.rfq-body .wpcf7-spinner,
.form-card .wpcf7-spinner { display: inline-block; }

/* Honeypot / hidden CF7 fields must never take up space. */
.wpcf7 .wpcf7-form-control-wrap[data-name^="_"],
.wpcf7 .ntm-hp { position: absolute !important; left: -9999px; }

/* --------------------------------------------------------------------------
   5. WYSIWYG content coming out of ACF / the classic editor
   -------------------------------------------------------------------------- */
.rich > *:first-child,
.body > *:first-child,
.text-block > *:first-child { margin-top: 0; }

.alignleft  { float: left;  margin: 0 24px 16px 0; }
.alignright { float: right; margin: 0 0 16px 24px; }
.aligncenter { display: block; margin-inline: auto; }
.alignnone { display: block; }

img.wp-post-image,
.rich img,
.text-block img { max-width: 100%; height: auto; border-radius: var(--radius); }

.wp-caption { max-width: 100%; }
.wp-caption-text {
  font-family: var(--mono);
  font-size: .7rem;
  color: var(--steel-500);
  margin-top: 6px;
}

/* --------------------------------------------------------------------------
   6. Blog / archive / search / 404 — templates the prototype never had
   -------------------------------------------------------------------------- */
.entry-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 26px;
  margin-top: 40px;
}
.entry-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--steel-100);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: var(--shadow-md);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.entry-card:hover { transform: translateY(-4px); }
.entry-card img { width: 100%; aspect-ratio: 3/2; object-fit: cover; }
.entry-card__body { padding: 22px 24px 26px; }
.entry-card__meta {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--steel-500);
}
.entry-card__body h3 { font-size: 1.25rem; margin-top: 8px; }
.entry-card__body h3 a { color: inherit; }
.entry-card__body h3 a:hover { color: var(--teal-bright); }
.entry-card__body p { color: var(--steel-700); margin-top: 10px; font-size: .96rem; line-height: 1.65; }

.entry-content { max-width: 76ch; color: var(--steel-700); font-size: 1.04rem; line-height: 1.75; }
.entry-content h2 { margin-top: 1.6em; color: var(--ink); }
.entry-content h3 { margin-top: 1.4em; color: var(--ink); }
.entry-content p + p,
.entry-content ul,
.entry-content ol { margin-top: 1em; }
.entry-content ul,
.entry-content ol { padding-left: 1.3em; }
.entry-content li + li { margin-top: .4em; }
.entry-content blockquote {
  border-left: 3px solid var(--gold);
  padding-left: 20px;
  margin: 1.4em 0;
  font-size: 1.1rem;
}
.entry-content a { color: var(--teal-bright); text-decoration: underline; }

.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 48px;
  font-family: var(--cond);
  font-weight: 600;
}
.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  padding: 9px 14px;
  border: 1px solid var(--steel-100);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--steel-700);
}
.pagination .page-numbers:hover,
.pagination .page-numbers.current {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--ink);
}

.search-form-inline { display: flex; gap: 10px; margin-top: 26px; max-width: 460px; }
.search-form-inline input[type="search"] {
  flex: 1;
  font-family: var(--display);
  font-size: .95rem;
  padding: 11px 14px;
  border: 1px solid var(--steel-100);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
}
.search-form-inline input[type="search"]:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(255,211,70,.16);
}

.error-404 .code {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(5rem, 18vw, 12rem);
  line-height: .85;
  color: rgba(255,255,255,.14);
  letter-spacing: -.04em;
}

/* --------------------------------------------------------------------------
   7. Footer credit
   --------------------------------------------------------------------------
   A third item in .footer-bottom, which is already flex + space-between +
   wrap, so it takes the right-hand slot on desktop and stacks on mobile.
   -------------------------------------------------------------------------- */

.footer-credit { color: var(--steel-500); }
.footer-credit a {
  color: var(--steel-300);
  border-bottom: 1px solid rgba(159, 180, 189, .3);
  transition: color .2s, border-color .2s;
}
.footer-credit a:hover,
.footer-credit a:focus-visible {
  color: var(--gold);
  border-bottom-color: var(--gold);
}

@media (max-width: 720px) {
  /* Three items at this width read better stacked than squeezed. */
  .footer-bottom { flex-direction: column; gap: 10px; }
}

/* --------------------------------------------------------------------------
   8. Prototype bug fixes
   --------------------------------------------------------------------------
   Faults carried over from the static build. Fixed here rather than in
   style.css so that file stays diffable against the original.
   -------------------------------------------------------------------------- */

/* The mobile drawer was only ever ~130px tall, clipping all thirteen links to
   the first one.

   .site-header carries `backdrop-filter: blur(12px)`, and a backdrop-filter
   makes an element the containing block for its position:fixed descendants.
   The drawer (.nav, `position: fixed; inset: 0 0 0 auto`) was therefore sized
   against the header, not the viewport — then `overflow-y: auto` hid the
   overflow, so it looked like the menu simply had one item.

   Dropping the blur below 940px restores viewport-relative positioning. The
   header background is already 92% opaque, so the blur was doing almost
   nothing there; it is made fully opaque to compensate. Desktop keeps it. */
@media (max-width: 940px) {
  .site-header {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: #0d171c;
  }

  .nav {
    /* dvh tracks the collapsing mobile address bar; vh is the fallback. */
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    z-index: 101;
    overscroll-behavior: contain;
  }

  /* Keep the drawer clear of the admin bar for logged-in editors. */
  body.admin-bar .nav {
    top: 46px;
    height: calc(100dvh - 46px);
    max-height: calc(100dvh - 46px);
  }

  /* The "Why NTM" and "Credentials" sections collapsed into a single cell,
     stacking heading, value points and photo on top of each other.

     Both grids are laid out with named areas on desktop:

       .intro .wrap  { grid-template-areas: "head head" "points figure"; }
       .intro-head   { grid-area: head; }      etc.

     The prototype clears `grid-template-areas: none` at this breakpoint but
     leaves `grid-area` on the children. With no lines by those names left,
     the grid invents implicit ones — producing two zero-width columns, a
     zero-height row, and all three items resolving into the same cell.
     Measured before the fix: columns `0px 0px 281px` against a 353px
     container, with the children overlapping.

     Clearing the children's placement too is what makes the single-column
     reset actually take effect. They then flow in DOM order, which is already
     the order the mobile layout wants. */
  .intro-head,
  .intro-points,
  .intro-figure,
  .creds-head,
  .cred-list,
  .legacy-figure {
    grid-area: auto;
  }
}

/* --------------------------------------------------------------------------
   9. Motion preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .hero-video { display: none; }
}
