/* ==========================================================================
   03 OVERRIDES: changes to Nextmind itself
   ==========================================================================
   Anything that adjusts the parent theme's own output belongs here, not in
   the parent. Keep each block labelled with what it does and why.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Post byline on single posts

   Nextmind ships a meta row with the date and category only. No author and
   no last updated date. Both are E-E-A-T signals, and generative engines
   read the visible byline, not just the schema. The child theme's
   template-parts/single.php adds them; these are the styles.

   The markup deliberately reuses the parent's .post-single-meta ul/li
   pattern so it inherits the existing spacing and icon treatment.
   -------------------------------------------------------------------------- */

/* DO NOT set display:flex or inline-flex on these list items.
   ---------------------------------------------------------------------------
   Fixed in 1.2.2. An earlier version set `display: inline-flex` here to centre
   the icon against the text. That broke the byline, rendering it as
   "ByDaverick Aguilar" with no space.

   Why: under flex layout, whitespace-only text between flex items is
   discarded. The markup is `<i></i>By <span>Name</span>`, so the icon, the
   word "By" and the name each become flex items and the space between them
   is thrown away. The date and category items were unaffected because they
   are plain text after the icon, with no second element to flex against.

   The parent already sets `.post-single-meta ul li { display: inline-block }`
   and puts `margin-right: 8px` on the icon, which handles spacing correctly
   and keeps these items consistent with the date and category beside them.
   Inheriting that is the fix. */

.post-single-meta .geo-meta-author a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--geo-transition), color var(--geo-transition);
}

.post-single-meta .geo-meta-author a:hover,
.post-single-meta .geo-meta-author a:focus-visible {
  color: var(--geo-accent);
  border-bottom-color: var(--geo-accent);
}

/* The updated date is secondary information. Slightly quieter than the rest
   of the row so it reads as a footnote rather than competing with it. */
.post-single-meta .geo-meta-updated { opacity: 0.75; }


/* --------------------------------------------------------------------------
   Focus visibility

   The parent theme removes or does not define a visible focus ring in
   several places. Keyboard users need one. This is a WCAG 2.4.7 baseline
   and it costs nothing visually for mouse users, because :focus-visible
   only fires for keyboard navigation.
   -------------------------------------------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--geo-accent);
  outline-offset: 2px;
}


/* --------------------------------------------------------------------------
   Skip link

   Nextmind outputs a skip link but relies on .screen-reader-text to hide
   it. Make sure it becomes visible on focus, otherwise it is useless.
   -------------------------------------------------------------------------- */

.skip-link.screen-reader-text:focus {
  background: var(--geo-surface);
  color: var(--geo-text-bright);
  border: 1px solid var(--geo-accent);
  border-radius: var(--geo-radius-sm);
  clip: auto !important;
  clip-path: none;
  display: block;
  font-size: var(--geo-fs-small);
  font-weight: var(--geo-fw-bold);
  height: auto;
  left: var(--geo-space-md);
  line-height: normal;
  padding: var(--geo-space-sm) 24px;
  text-decoration: none;
  top: var(--geo-space-md);
  width: auto;
  z-index: 100000;
}


/* --------------------------------------------------------------------------
   Tables inside post content

   The case study and the rankings blog post both use hand written HTML
   tables. Nextmind has no table styling of its own, so they inherit
   browser defaults and overflow on mobile. This makes them scroll
   horizontally instead of breaking the layout.
   -------------------------------------------------------------------------- */

.post-entry table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--geo-space-lg) 0;
  font-size: var(--geo-fs-small);
}

.post-entry table th,
.post-entry table td {
  padding: var(--geo-space-sm) 16px;
  border: 1px solid var(--geo-border);
  text-align: left;
  vertical-align: top;
}

.post-entry table th {
  background: var(--geo-surface-alt);
  color: var(--geo-text-bright);
  font-weight: var(--geo-fw-bold);
}

.post-entry table td { color: var(--geo-text-soft); }

@media (max-width: 700px) {
  /* Wrap a table in <div class="geo-table-scroll"> if it still overflows. */
  .geo-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: var(--geo-space-lg) 0;
  }
  .geo-table-scroll table { margin: 0; min-width: 560px; }
}


/* --------------------------------------------------------------------------
   Images inside post content

   Stops full width chart exports from overflowing their column on mobile.
   -------------------------------------------------------------------------- */

.post-entry img {
  max-width: 100%;
  height: auto;
}


/* --------------------------------------------------------------------------
   Contact Form 7 submit feedback

   The form takes a few seconds to respond and previously showed nothing in
   between, so people clicked again. Contact Form 7 would normally render a
   spinner beside the button, but on this site it does not: the button has
   the `has-spinner` class and no spinner element is output.

   These rules pair with assets/js/form-feedback.js, which watches the
   `data-status` attribute CF7 puts on the form.
   -------------------------------------------------------------------------- */

.wpcf7-form .wpcf7-submit {
  transition: opacity var(--geo-transition);
}

/* While sending: dim the button, stop mouse clicks, show a spinner.
   The JS also swaps the label to "Sending..." and blocks the Enter key,
   because pointer-events does not stop keyboard submission. */
.wpcf7-form[data-status="sending"] .wpcf7-submit {
  opacity: 0.6;
  pointer-events: none;
  cursor: wait;
}

.geo-form-spinner {
  display: none;
  width: 18px;
  height: 18px;
  margin: var(--geo-space-sm) auto 0;
  border: 2px solid var(--geo-border-strong);
  border-top-color: var(--geo-accent);
  border-radius: 50%;
  animation: geo-spin 0.7s linear infinite;
}

.wpcf7-form[data-status="sending"] .geo-form-spinner { display: block; }

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

/* Someone who has asked for reduced motion still needs to know something is
   happening, so pulse the opacity instead of spinning. */
@media (prefers-reduced-motion: reduce) {
  .geo-form-spinner {
    animation: geo-pulse 1.2s ease-in-out infinite;
    border-top-color: var(--geo-border-strong);
    background: var(--geo-accent);
  }
  @keyframes geo-pulse {
    0%, 100% { opacity: 0.35; }
    50%      { opacity: 1; }
  }
}

/* --------------------------------------------------------------------------
   Contact Form 7 response messages

   These were previously styled only under `body.page-id-7844`. The live GEO
   audit page is 7859, so those rules had stopped applying and the success
   and error messages were falling back to Contact Form 7's defaults.

   Styled generically here so it does not matter what the page ID is.
   -------------------------------------------------------------------------- */

.wpcf7-form .wpcf7-response-output {
  border: none;
  border-left: 3px solid var(--geo-border-strong);
  border-radius: 0 var(--geo-radius-sm) var(--geo-radius-sm) 0;
  font-family: var(--geo-font);
  font-size: var(--geo-fs-small);
  line-height: 1.5;
  margin: var(--geo-space-md) 0 0;
  padding: var(--geo-space-sm) 16px;
}

.wpcf7-form.sent .wpcf7-response-output {
  background: var(--geo-success-bg);
  border-left-color: var(--geo-success);
  color: var(--geo-success);
}

.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7-form.failed .wpcf7-response-output,
.wpcf7-form.spam .wpcf7-response-output,
.wpcf7-form.aborted .wpcf7-response-output,
.wpcf7-form.unaccepted .wpcf7-response-output {
  background: var(--geo-error-bg);
  border-left-color: var(--geo-error);
  color: var(--geo-error);
}

.wpcf7-form .wpcf7-not-valid-tip {
  color: var(--geo-error);
  font-family: var(--geo-font);
  font-size: var(--geo-fs-fine);
  margin-top: 4px;
}


/* --------------------------------------------------------------------------
   Archive cards

   THE TRUNCATION PROBLEM THIS SOLVES
   The parent sets `height: calc(100% - 30px)` with `overflow: hidden` on the
   card. Long titles are not shortened, they are hidden behind the edge, so
   the cut lands wherever it lands, often mid-word, with no ellipsis.

   Replaced with explicit line clamps: two lines of title, three of excerpt,
   with a real ellipsis. The card becomes a flex column so the Read More
   button sits on the baseline regardless of how much text is above it, and
   every card in a row ends up the same height.
   -------------------------------------------------------------------------- */

.blog-style-1 .post-item.geo-card {
  display: flex;
  flex-direction: column;
  overflow: visible;
}

.geo-card .post-item-content {
  flex: 1 1 auto;
  min-width: 0;
}

/* Title: two lines, then ellipsis. */
.blog-style-1 .geo-card .post-item-content h2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Excerpt: three lines, then ellipsis. A manual excerpt of roughly 20 to 25
   words lands inside this comfortably. */
.blog-style-1 .geo-card .post-item-content > p {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.geo-card .post-item-btn { margin-top: auto; }


/* --- Card meta row: date and reading time --------------------------------- */

.geo-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--geo-space-sm);
}

.geo-card-meta p { margin-bottom: 0; }

.geo-card-readtime {
  font-family: var(--geo-font);
  font-size: var(--geo-fs-fine);
  color: var(--geo-text-muted);
}

.geo-card-readtime i { margin-right: 6px; }


/* --- Category chips ------------------------------------------------------- */

.geo-card-chips {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.geo-card-chip {
  font-family: var(--geo-font);
  font-size: var(--geo-fs-micro);
  font-weight: var(--geo-fw-semi);
  letter-spacing: 0.02em;
  color: var(--geo-text-chip);
  background: var(--geo-surface-chip);
  border: 1px solid var(--geo-border-chip);
  border-radius: var(--geo-radius-pill);
  padding: 3px 10px;
  white-space: nowrap;
}


/* --- Case study result highlights ----------------------------------------- */

.geo-card-highlights {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.geo-card-highlights li {
  position: relative;
  padding-left: 16px;
  font-family: var(--geo-font);
  font-size: var(--geo-fs-fine);
  font-weight: var(--geo-fw-semi);
  color: var(--geo-text-body);
  line-height: 1.45;
}

.geo-card-highlights li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--geo-accent);
}

@media (max-width: 767px) {
  .blog-style-1 .geo-card .post-item-content h2 {
    -webkit-line-clamp: 3;
    line-clamp: 3;
  }
}


/* --------------------------------------------------------------------------
   ElementsKit blog posts widget: equal card heights

   The AI Search Blog page is an Elementor page using the ElementsKit
   "blog posts" widget, NOT the theme's archive template. So the theme's own
   card rules do not reach it and the cards size to their content, which is
   why a row can have three different heights.

   The markup is:
     .row.ekit-blog-posts-content > .col-lg-4 > .elementskit-post-card

   Rather than percentage heights, which need a definite height on the parent
   to resolve, the column is made a flex container and the card is told to
   fill it. That works whatever the row is doing, and it survives ElementsKit
   changing its own margins, which it sets per-widget from the Elementor UI.
   -------------------------------------------------------------------------- */

.ekit-blog-posts-content { align-items: stretch; }

.ekit-blog-posts-content > [class*="col-"] {
  display: flex;
  flex-direction: column;
}

.ekit-blog-posts-content .elementskit-post-card {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

.ekit-blog-posts-content .elementskit-post-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

/* Pin Read More to the bottom of every card so the buttons line up. */
.ekit-blog-posts-content .btn-wraper { margin-top: auto; }

/* Belt and braces on length. ElementsKit trims the title and excerpt by word
   count in its own widget settings, so these clamps normally do nothing. They
   matter the moment those limits are raised, which stops a longer title
   pushing one card out of line again. */
.ekit-blog-posts-content .elementskit-post-card .entry-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ekit-blog-posts-content .elementskit-post-body > p {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
