/* New grid-tile hover logos (2026-08) — Vizop and Viviane Chen have no
   original-site counterpart, so no legacy width override exists for them.
   Starting widths for horizontal wordmark logos; tweak as needed. */
.thumb-item.vizop-logo {
  width: 65%;
}
.thumb-item.viviane-logo {
  width: 65%;
}

/* Rewritten interaction: .blog-main-img-con's base rule is `display: none`
   in egons-portfolio-3-0.css with no responsive override anywhere in the
   ported CSS — almost certainly a Webflow IX2 "page load" reveal state
   (hidden until the JS animation shows it), same pattern as .hover-overlay
   below. We don't port webflow.js, so the blog banner image silently never
   showed on any blog post. Force it visible instead of animating it in. */
.blog-main-img-con {
  display: block !important;
}

/* Rewritten interaction: the original relied on Webflow's IX2 engine
   (webflow.js) to reveal .hover-overlay on hover. We don't port that JS —
   this is the same reveal done in plain CSS. */
.hover-overlay {
  transition: opacity 0.25s ease;
}
.link-to-page:hover .hover-overlay,
.link-to-page:focus-visible .hover-overlay {
  opacity: 1;
}

/* Rewritten interaction: case-study body links (the "Go to ___ website"
   pattern — .link-block > .work-link-block > .link-line). We don't port
   Webflow's IX2 JS; this reproduces the exact same interaction in CSS,
   pulled from the original site's compiled bundle ("link line on"/"link
   line off" action lists in egons-portfolio-3-0.js):
   rest = 100px -> hover = 50px (200ms, "bounce") -> mouse-out = 100px
   (200ms, "bouncePast"). Both directions approximated with one overshoot
   cubic-bezier, since a single CSS transition runs symmetrically. */
.link-line {
  transition: width 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.link-block:hover .link-line {
  width: 50px !important;
}

/* RichText (About Me / Services) renders paragraphs as <div class="text">
   instead of <p class="text"> (hydration-safety — see RichText.tsx), so it
   misses components.css's `p { margin-bottom: 10px }`. Restore that spacing. */
div.text {
  margin-bottom: 10px;
}

/* ============================================================
   PRICE ESTIMATOR (#pricing) — NEW section, no original-design
   counterpart (user-requested, 2026-07). Styled to match the
   site's look: midnight-blue, poppins for controls, pt-sans-pro
   for prose. TO REMOVE the feature: delete this block, the
   PriceEstimator component/global, and its page.tsx wiring.
   ============================================================ */
.estimator-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
  margin: 24px 0;
}
.estimator-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.estimator-btn {
  background-color: transparent;
  border: 2px solid var(--midnight-blue);
  color: var(--midnight-blue);
  padding: 8px 18px;
  font-family: poppins, sans-serif;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.estimator-btn:hover {
  background-color: #e4e4e4;
}
.estimator-btn.is-active {
  background-color: var(--midnight-blue);
  color: #e4e4e4;
}
.estimator-factor {
  margin-bottom: 18px;
}
.estimator-factor-label {
  color: #5f5f5f;
  font-family: poppins, sans-serif;
  font-size: 18px;
  margin-bottom: 8px;
}
.estimator-result {
  border-top: 4px solid var(--midnight-blue);
  margin: 30px 0 18px;
  padding-top: 18px;
}
.estimator-result-label {
  color: #5f5f5f;
  font-family: poppins, sans-serif;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.estimator-result-range {
  color: var(--midnight-blue);
  font-family: poppins, sans-serif;
  font-size: 42px;
  font-weight: 800;
  line-height: 1.3;
  animation: estimator-range-fade-in 250ms ease;
}
@keyframes estimator-range-fade-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.estimator-disclaimer {
  color: #5f5f5f;
  font-size: 18px;
  line-height: 26px;
}
@media (max-width: 767px) {
  .estimator-result-range {
    font-size: 30px;
  }
}
/* ================== END PRICE ESTIMATOR ===================== */

/* ============================================================
   BLOG GRID RESTYLE (deviation from the original design, 2026-07)
   Requested: no blur on thumbnails; title + category in a solid
   strip at the bottom of the card instead of overlaying the image;
   title in the site's default text color (#333).
   TO REVERT to the original ported look: delete this entire block.
   ============================================================ */

/* Card becomes a flex column: image on top, text strip below. */
.grid-blocks.blog {
  background-color: var(--white-smoke);
  flex-direction: column;
  display: flex;
}

/* Image area: flows above the strip, no blur/dimming. */
.grid-blocks.blog .blog-block-bg {
  order: 1;
  flex: 1 1 auto;
  min-height: 0;
  opacity: 1;
  filter: none;
}
.grid-blocks.blog .blog-block-bg:hover {
  filter: none;
}

/* Link drops out of absolute positioning to become the strip… */
.grid-blocks.blog .link-to-page {
  order: 2;
  position: static;
  width: 100%;
  height: auto;
}
/* …but a full-card pseudo keeps the whole card clickable. */
.grid-blocks.blog .link-to-page::after {
  content: '';
  position: absolute;
  inset: 0;
}

.grid-blocks.blog .blog-block-inside {
  height: auto;
  padding: 12px 15px;
  justify-content: flex-start;
  align-items: flex-start;
}

.grid-blocks.blog .blog-block-header {
  color: #333;
}

/* Excerpt (.block-p, restored from the original cards): original styling
   was light text centered over the image — restyled for the white strip. */
.grid-blocks.blog .block-p {
  color: #333;
  text-align: left;
  margin-bottom: 10px;
}

/* Masonry: CSS columns instead of the original's fixed-row grid; cards
   take their natural height and images keep their intrinsic aspect. */
.blog-grid {
  display: block;
  columns: 4;
  column-gap: 0.25vw;
}
@media (max-width: 1400px) {
  .blog-grid {
    columns: 3;
  }
}
@media (max-width: 991px) {
  .blog-grid {
    columns: 2;
  }
}
.grid-blocks.blog {
  break-inside: avoid;
  height: auto;
  margin-bottom: 0.25vw;
}
.grid-blocks.blog .blog-block-bg {
  flex: none;
}
.grid-blocks.blog .blog-block-img {
  height: auto;
}
/* ================== END BLOG GRID RESTYLE =================== */

/* BP Gallery spans 2 columns, and Gobee moves to the very end of the grid,
   only at the small (<=991px, 2-column) work-grid breakpoint — both stay at
   their normal desktop values (BP span 1, Gobee mid-sequence per its CMS
   `order`) at every wider breakpoint. Combined, this fills the 2-column
   grid with zero gaps: without both changes, Gobee (1-col) sits directly
   before L9L's 2-col span, and since .portfolio._2 has no
   grid-auto-flow: dense (dense would reorder every tile out of its
   deliberate sequence, which isn't wanted), CSS Grid's sparse auto-flow
   leaves that gap unfillable. The CSS `order` property is respected by
   grid auto-placement the same way it is in flexbox, so bumping Gobee's
   order above every other tile pushes it to the end of the placement
   sequence at this breakpoint only — no change to the CMS `order` field
   or the DOM order needed. */
@media screen and (max-width: 991px) {
  .grid-blocks:has(.port-container.bp) {
    grid-column: span 2;
  }

  .grid-blocks:has(.port-container.gobee) {
    order: 1;
  }
}

/* Extra breathing room at the very top/bottom of the homepage's content
   flow — About is the first section after the splash hero, Pricing is the
   last before Contact. Additive on top of .about-container's own 45px
   padding (so About gets 90+45=135px above its heading, Pricing gets
   45+90=135px below its content), not a replacement for it. */
#about {
  padding-top: 90px;
}

#pricing {
  padding-bottom: 90px;
}

#contact {
  padding-top: 90px;
}
