/* tutor-detail page ("/tutor/{slug}") — visual/structural redesign of the
   existing, fully-functional real tutor profile page
   (resources/views/frontend/tutor-detail.blade.php +
   app/Http/Controllers/Frontend/SearchController::tutorDetail +
   app/Services/SiteService::getTutorDetail). Ported from mentor-template.md
   (a build spec studying scrollix-local-4's hand-authored mentor.html),
   same adaptation approach already used for find-tutors-page.css:
   - "Restyle the existing real page" (per user's explicit choice): every
     complex real Livewire component (tutor-sessions booking calendar,
     students-reviews, tutor-resume) keeps its own internal markup/behavior
     100% untouched — only wrapped in new section chrome (heading/badge/
     spacing) for visual consistency. Their own am-* classes are NOT
     restyled here except where a wrapper explicitly wants a new
     background/heading treatment around them.
   - similar-tutors.blade.php WAS restyled in place (explicitly requested,
     "reuse card/badge styles from the redesigned mentor cards") to reuse
     the .ft-tutorcard design from find-tutors-page.css — that ruleset is
     intentionally duplicated below (not cross-loaded) to keep this page's
     stylesheet self-contained, matching this project's established
     one-stylesheet-per-page convention.
   - .am-btn/.am-white-btn/.am-likebtn (from <livewire:pages.tutor.action.action>,
     reused unchanged) are visually reskinned via page-scoped selectors only
     (e.g. ".tp-hero-cta-row .am-btn"), never by editing the global button
     classes — so no other page using those same classes is affected.
   - Host Grotesk / Inter and the #ff6363 coral match this project's
     established palette (scrollix-sections.css / find-tutors-page.css). */

/* No overflow-x:hidden here (unlike find-tutors-page.css's equivalent
   .ft-page-extra) — an ancestor with any non-visible overflow value is a
   well-known way to silently break position:sticky for every descendant,
   which is exactly what disabled the pricing sidebar's stickiness. Not
   needed for containment on this page anyway: the hero background's own
   100vw-wide layer is already locally clipped by .tp-hero-clip's own
   overflow:hidden, and every breakpoint has been verified to produce zero
   horizontal overflow without this rule. */
.tp-page-extra {
  font-family: "Capriola", sans-serif;
  color: #171717;
}

.tp-container {
  margin: 0 auto;
}

.tp-section {
  padding: 56px 0;
}
@media (max-width: 810px) {
  .tp-section {
    padding: 36px 0;
  }
}

.tp-badge {
  display: flex;
  align-items: center;
  justify-content: start;
  gap: 10px;
  color: #ff6363;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 20px;
}
.tp-badge::before,
.tp-badge::after {
  content: "";
  width: 24px;
  height: 1px;
  background: currentColor;
}

.tp-h2 {
  font-family: "Capriola", sans-serif;
  font-size: clamp(30px, 4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: #020202;
  margin: 0;
}

.tp-section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 28px;
}

/* ============ HERO ============ */

.tp-hero {
  position: relative;
  padding: 200px 0 48px;
}

@media (max-width: 640px) {
  .tp-hero {
    padding-top: 150px;
  }
}

.tp-hero-clip {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 20px;
  overflow: hidden;
}
.tp-hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 20px;
  top: 10px;
  bottom: 20px;
  left: 50%;
  width: calc(100vw - 40px);
  transform: translateX(-50%);
}

@media (max-width: 767px) {
  .tp-hero-bg {
    width: calc(100vw - 20px);
  }
}

.tp-hero-bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border-radius: inherit;
  mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
}

#tp-hero-inner {
  position: relative;
  z-index: 2;
}

.tp-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
  align-items: center;
}

.tp-hero-grid > * {
  min-width: 0;
}

@media (min-width: 950px) {
  .tp-hero-grid {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 48px;
  }
}

.tp-eyebrow {
  display: inline-flex;
  align-items: center;
  font-size: 15px;
  font-weight: 700;
  color: #ff6363;
  margin-bottom: 20px;
  gap: 8px;
  background: #fff1f1;
  border-radius: 999px;
  padding: 8px 16px;
}
.tp-eyebrow-dot {
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 999px;
  background: #ff6363;
}

/* No max-width/overflow guard on purpose would let a very long real name
   overflow — clamp() keeps it from ever exceeding its column, and
   overflow-wrap covers a single unbroken long word/diacritic-heavy name
   (flagged as fragile in mentor-template.md; fixed here rather than
   ported as-is). */
.tp-hero-name {
  font-family: "Capriola", sans-serif;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  font-size: clamp(34px, 6.5vw, 68px);
  color: #020202;
  margin: 0 0 18px;
  overflow-wrap: break-word;
  word-break: break-word;
}
.tp-hero-name .tp-verified {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 6px;
}

.tp-hero-intro {
  font-size: clamp(17px, 1.4vw, 20px);
  line-height: 1.6;
  color: #4a4a4a;
  max-width: 520px;
  margin: 0 0 28px;
}

.tp-hero-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 28px;
}
.tp-hero-stat {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 16px;
  color: #4a4a4a;
}
.tp-hero-stat .tp-star {
  color: #ffb100;
}
.tp-hero-stat-value {
  font-family: "Capriola", sans-serif;
  font-size: 21px;
  font-weight: 700;
  color: #020202;
}
.tp-hero-stat-label {
  font-size: 15px;
  color: #8a8a8a;
}
.tp-hero-divider {
  width: 1px;
  height: 28px;
  background: rgba(0, 0, 0, 0.1);
  flex-shrink: 0;
}

.tp-hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
/* Plain real anchor (jumps to the real booking calendar, #availability) —
   not a Livewire component; see _hero.blade.php's comment for why
   book/message/favorite live as a single instance in the sidebar's
   #tp-pricing-build instead, reparented here by initPhotoMorph while the
   user is still near the top of the page. */
.tp-hero-book-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 52px;
  padding: 0 26px;
  border-radius: 999px;
  font-size: 16.5px;
  font-weight: 600;
  text-decoration: none;
  border: none;
  transition: transform 150ms ease, box-shadow 150ms ease;
  background: linear-gradient(38deg, #ffbcbc 0%, #ff6363 54.0541%);
  color: #fff;
  /* box-shadow: 0 14px 30px -12px rgba(255, 99, 99, 0.6); */
}
.tp-hero-book-btn:hover {
  transform: translateY(-1px);
  color: #fff;
}

/* Social links row — the mentor card's own social-icon row was dropped in
   its full-photo redesign, so this is now the only place a tutor's real
   social links (User::socialProfiles()) are shown. Plain in-flow row (not
   the card's absolutely-positioned-over-a-photo treatment) since this sits
   on ordinary page background, not an image. */
.tp-hero-social-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}
.tp-hero-social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  /* background: #fff; */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.tp-hero-social-btn img {
  width: 18px;
  height: 18px;
  display: block;
}

.tp-hero-portrait-col {
  display: flex;
  justify-content: end;
}
.tp-hero-portrait-wrap {
  position: relative;
  max-width: 400px;
  width: 100%;
  /* margin: 0 18px; */
}
.tp-hero-portrait-wrap:hover .tp-hero-portrait img {
  transform: scale(1.05);
}
.tp-hero-portrait {
  position: relative;
  border: 5px solid #fff;
  border-radius: 32px;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  box-shadow: 0 30px 60px -20px rgba(2, 2, 2, 0.28),
    0 0 0 1px rgba(0, 0, 0, 0.04);
  padding: 15px;
  background: #fff;
}
.tp-hero-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 400ms;
  border-radius: 20px;
}
.tp-hero-portrait-shade {
  position: absolute;
  inset: 0;
  /* background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0) 55%,
    rgba(0, 0, 0, 0.55) 100%
  ); */
}
.tp-hero-online {
  position: absolute;
  left: 18px;
  bottom: 18px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.95);
  color: #171717;
  font-size: 14.5px;
  font-weight: 600;
}
.tp-ping {
  position: relative;
  width: 9px;
  height: 9px;
  flex-shrink: 0;
}
.tp-ping-dot {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #22a559;
}
.tp-ping::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #22a559;
  animation: tp-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes tp-ping {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  75%,
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}

.tp-hero-badge-price {
  position: absolute;
  left: -18px;
  top: -18px;
  transform: rotate(-6deg);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  background: #fff;
  border-radius: 18px;
  padding: 12px 16px;
  box-shadow: 0 20px 40px -26px rgba(2, 2, 2, 0.22),
    0 0 0 1px rgba(0, 0, 0, 0.05);
}
@media (max-width: 640px) {
  .tp-hero-badge-price {
    left: -8px;
    top: -8px;
  }
}
.tp-hero-badge-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8a8a8a;
}
.tp-hero-badge-value {
  font-family: "Capriola", sans-serif;
  font-size: 23px;
  font-weight: 700;
  color: #020202;
}
.tp-hero-badge-value small {
  font-size: 15px;
  font-weight: 500;
  color: #8a8a8a;
  margin-left: 2px;
}

/* ============ MAIN TWO-COLUMN GRID ============ */

/* align-items: stretch (the grid default) is required, not just cosmetic —
   .tp-sidebar (the grid item) is stretched to match .tp-main-content's
   full height (now bio+course+video+reviews, per explicit request that
   the sidebar keep sticking down through Reviews). Sticky positioning
   itself lives one level deeper, on .tp-sidebar-sticky (see
   _pricing-sidebar.blade.php's comment): sticky's available "slack" is
   (containing block height − the sticky element's OWN height), so the
   element that's actually `position:sticky` must stay at its natural
   (short) height — stretching THAT element directly (tried first) leaves
   zero slack and makes sticky behave exactly like static positioning,
   which is what was happening before this two-wrapper structure. */
.tp-main-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  align-items: stretch;
  justify-items: end;
}

@media (min-width: 1024px) {
  .tp-main-grid {
    min-height: 780px;
    grid-template-columns: minmax(0, 1fr) 460px;
  }
}
.tp-main-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.tp-main-content > * + * {
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}
@media (max-width: 1023px) {
  .tp-sidebar {
    display: none;
  }
}
@media (min-width: 1024px) {
  .tp-sidebar-sticky {
    position: sticky;
    top: 32px;
  }
}
.tp-sidebar {
  min-width: 0;
  padding-bottom: 56px;
  max-width: 400px;
  margin-left: 17px;
}

/* ============ BIO ============ */
/* Reuses the EXISTING real show-more mechanism (.am-toggle-text/.am-addmore/
   .short-description/.full-description/.toggle-description + the jQuery
   handler already registered in tutor-detail.blade.php) — only restyled,
   not reimplemented, per "don't drop existing behavior". */

.tp-bio-wrap .am-addmore {
  position: relative;
}
.tp-bio-p {
  font-size: 19px;
  line-height: 1.7;
  color: #4a4a4a;
  margin: 0;
}
.tp-bio-dropcap:first-letter {
  float: left;
  font-family: "Capriola", sans-serif;
  font-size: 60px;
  line-height: 0.8;
  font-weight: 700;
  color: #020202;
  margin: 4px 8px 0 0;
}
.tp-bio-wrap .toggle-description {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  font-size: 16px;
  font-weight: 600;
  color: #4a4a4a;
  text-decoration: none;
}
.tp-bio-wrap .toggle-description::after {
  content: "";
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  margin-top: -4px;
  transition: transform 200ms ease;
}

/* ============ SUBJECTS & LANGUAGES (real data — replaces the spec's
   free-text "course.description", which has no per-tutor equivalent in
   this project's data model; subjects taught + languages spoken are the
   real, already-existing content closest to that section's intent) */

.tp-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.tp-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  /* background: #fff; */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
  color: #171717;
  font-size: 15.5px;
  /* font-weight: 600; */
}
.tp-pill-group {
  margin-bottom: 22px;
}
.tp-pill-group:last-child {
  margin-bottom: 0;
}
.tp-pill-group-label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: #8a8a8a;
  margin-bottom: 10px;
}

/* ============ SUBJECT TABS (interactive "Subjects I teach") ============
   Reuses .tp-pill's own pill shape/shadow for the unselected tab state and
   .tp-hero-book-btn's coral gradient for the booking CTA — same tokens as
   the rest of this page, not the Modernist source design's own red-orange/
   sharp-corner palette. */
.tp-subject-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 50px;
}
.tp-subject-tab {
  appearance: none;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: 999px;
  background: transparent;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
  color: #171717;
  font: inherit;
  font-size: 15.5px;
  font-weight: 600;
  transition: background 150ms ease, color 150ms ease, box-shadow 150ms ease;
}
.tp-subject-tab:hover {
  background: #fff1f1;
}
.tp-subject-tab.is-active {
  background: linear-gradient(38deg, #ffbcbc 0%, #ff6363 54.0541%);
  color: #fff;
  box-shadow: none;
}

/* Wrapping container the cross-fade/height transition below animates (see
   initSubjectTabs() in tutor-detail-page.js) — position:relative anchors
   the two absolutely-positioned panels JS overlaps mid-transition, and
   overflow:hidden clips whichever one is taller while the container's
   height is still animating between the old and new panel's heights. */
.tp-subject-panels {
  position: relative;
  overflow: hidden;
}

.tp-subject-panel[hidden] {
  display: none;
}

.tp-subject-panel {
  padding: 20px;
  min-height: 350px;
  border-radius: 20px;
  border: 1px solid #d1d1d1;
}

/* Safety net: initSubjectTabs() already checks prefers-reduced-motion in
   JS and skips the animated path entirely, but this guards against any
   transition style it may have left mid-flight. */
@media (prefers-reduced-motion: reduce) {
  .tp-subject-panels,
  .tp-subject-panel {
    transition: none !important;
  }
}

.tp-subject-name {
  font-family: "Capriola", sans-serif;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 10px;
  color: #020202;
}
.tp-subject-price {
  display: inline-flex;
  width: fit-content;
  padding: 6px 16px;
  border-radius: 999px;
  background: #fff1f1;
  color: #ff6363;
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 28px;
}

.tp-subject-eyebrow {
  margin-bottom: 14px;
}
.tp-subject-hr {
  height: 1px;
  border: 0;
  margin: 0 0 24px;
  background: rgba(0, 0, 0, 0.08);
}

.tp-subject-media {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 28px;
}
@media (max-width: 700px) {
  .tp-subject-media {
    flex-direction: column;
  }
}
.tp-subject-photo {
  flex: 0 0 38%;
  border-radius: 20px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
}
.tp-subject-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Muted editorial treatment, straight from the source design. */
  filter: grayscale(1) contrast(1.08);
}
.tp-subject-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
/* No-photo state: description fills the full row width instead of the
   photo's slot, no icon placeholder standing in for the missing image. */
.tp-subject-media--no-photo .tp-subject-text {
  flex: 1 1 100%;
}
.tp-subject-desc {
  font-size: 15px;
  line-height: 1.6;
  color: #4a4a4a;
  margin: 0 0 20px;
}
.tp-subject-cta {
  align-self: flex-start;
  /* Pushes to the bottom of the text column regardless of description
     length, so the button lands in the same place across subjects
     instead of drifting with content length. */
  margin-top: auto;
}

/* ============ VIDEO ============ */

.tp-video-wrap {
  position: relative;
  border-radius: 24px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: #020202;
}
.tp-video-wrap video,
.tp-video-wrap .video-js {
  width: 100%;
  height: 100%;
}

/* ============ REVIEWS / RESUME WRAPPERS ============
   The real <livewire:components.students-reviews> / <livewire:components.tutor-resume>
   keep their own internal am-* visuals entirely — these wrappers only add
   the new section badge/heading above them for visual rhythm with the
   rest of the page. */

.tp-subsection-head {
  margin-bottom: 8px;
}

/* ============ PRICING SIDEBAR ============ */

.tp-pricing-card {
  background: #fff;
  border-radius: 28px;
  overflow: hidden;
  box-shadow: 0 30px 60px -20px rgba(2, 2, 2, 0.22),
    0 0 0 1px rgba(0, 0, 0, 0.04);
}

.booking-wizard-sidebar .tp-pricing-card {
  box-shadow: unset;
  border: 1px solid #d1d1d1;
}

.tp-sidebar-photo {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border: 5px solid #fff;
  padding: 15px;
}
.tp-sidebar-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 6%;
}

/* Name/subject-line/bio block between the photo and the meta rows — used by
   components/frontend/tutor-mini-profile.blade.php (shared by this page's
   own sidebar and the booking wizard's sidebar). Downsized versions of the
   hero's own .tp-h2/.tp-hero-intro for this narrower column, not new type
   tokens. */
.tp-sidebar-info {
  padding: 22px 22px 4px;
}
.tp-sidebar-name {
  font-size: 22px;
  margin-bottom: 6px;
}
/* Name is a real link to the tutor's profile (booking wizard sidebar only
   — hidden via show-info=false on this page's own pricing sidebar). Global
   `a` styling (public/css/main.css) is blue/no-underline; override to match
   this heading's existing dark color, with an underline only on hover as
   the click affordance. */
.tp-sidebar-name a {
  color: inherit;
}
.tp-sidebar-name a:hover {
  color: inherit;
  text-decoration: underline;
}
.tp-sidebar-intro {
  font-size: 15px;
  margin-bottom: 16px;
}

/* #tp-pricing-build (meta rows + the one real action-component instance)
   grows via max-height driven by scroll progress (0 at the top of the
   page, full height once docked) — same technique + reasoning as
   mentor-template.md's own .tp-pricing-build: see initPhotoMorph's
   applyBuildGrowth in tutor-detail-page.js, which also staggers each
   .tp-pricing-meta-row/.tp-pricing-cta's own opacity/translateY as this
   grows, rather than one uniform fade inside an already-sized box. */
.tp-pricing-build {
  overflow: hidden;
  max-height: 0;
}

.tp-pricing-meta {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 22px;
  font-size: 15.5px;
  /* color: #ff6363; */
  /* One divider beneath the whole row group (not between individual rows)
     — sits right after this block's own bottom padding, before
     .tp-pricing-cta's buttons. */
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.tp-pricing-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.tp-pricing-meta-label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.tp-pricing-meta-value {
  flex-shrink: 0;
  white-space: nowrap;
}

.tp-pricing-meta-icon {
  display: inline-flex;
  flex-shrink: 0;
  color: #ff6363;
}
.tp-pricing-meta-icon svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Reskins the real, unmodified <livewire:pages.tutor.action.action>
   buttons (book/message/favorite) — scoped to this container only, so the
   global .am-btn/.am-white-btn/.am-likebtn classes used elsewhere in the
   app are untouched. Layout: book on its own full-width row, then
   message+favorite paired on a second row (message flexes, favorite stays
   a fixed-size icon circle) — mirrors this page's own hero CTA row
   pairing before book/message/favorite moved into this single reparented
   instance. */
.tp-pricing-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 16px 18px 20px;
}

.tp-pricing-cta > div {
  display: flex;
  justify-content: space-around;
  width: 100%;
  gap: 10px;
}

.tp-pricing-cta .am-btn,
.tp-pricing-cta .am-white-btn {
  /* flex: 1 1 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px; */
  height: 50px;
  padding: 0 20px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  border: none;
}

.tp-pricing-cta .am-contact-white-btn {
  background: #000;
  flex: 1;
}

.tp-pricing-cta .am-btn {
  background: linear-gradient(38deg, #ffbcbc 0%, #ff6363 54.0541%);
  color: #fff;
}
.tp-pricing-cta .am-white-btn {
  flex: 1 1 auto;
  background: #f7f7f8;
  color: #171717;
}
.tp-pricing-cta .am-btn i,
.tp-pricing-cta .am-white-btn i {
  display: none;
}
.tp-pricing-cta .am-likebtn {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: #ededed;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
}
.tp-pricing-cta .am-likebtn.active {
  background: #fff1f1;
}
.tp-pricing-cta .am-likebtn i::before {
  color: rgba(2, 2, 2, 0.5);
}
.tp-pricing-cta .am-likebtn.active i::before {
  color: #ff6363;
}

/* ============ SCROLL-LINKED PHOTO MORPH (hero portrait <-> sidebar photo,
   #tp-pricing-build reparented alongside it) ============
   The traveling "flyer": ONE fixed-position element containing the photo
   AND (reparented in from the real #tp-pricing-build while transiting —
   see initPhotoMorph in tutor-detail-page.js) the pricing build, so the
   photo's position/size and the build's growth are one continuous,
   visually-attached unit. top/left/width/height are interpolated every
   frame between the hero portrait's live rect and the sidebar photo's
   live rect; the photo portion's own height interpolates the same way,
   and .tp-pricing-build grows directly beneath it via max-height. Exact
   same structure/technique as mentor-template.md's .tp-photo-flyer. */
.tp-photo-flyer {
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  background: #fff;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  box-shadow: 0 30px 60px -20px rgba(2, 2, 2, 0.28),
    0 0 0 1px rgba(0, 0, 0, 0.04);
  /* This is appended to document.body (see initPhotoMorph in
     tutor-detail-page.js), outside .tp-page-extra's font-family:"Capriola", sans-serif;*/
}
/* #tp-pricing-build is the one real, functional node (the actual
   <livewire:pages.tutor.action.action> instance — Book/Message/Favorite)
   reparented into this otherwise-decorative flyer while it's in transit
   (see moveBuildTo in tutor-detail-page.js). Its content visually finishes
   animating in well before the flyer "docks" (applyBuildGrowth's per-row
   easing settles long before progress reaches the exact 1.0 threshold that
   moves it back into .tp-pricing-card) — so the flyer's own pointer-events:
   none, meant only to make the decorative photo click-through, was also
   silently blocking clicks on these real buttons for that whole window.
   Re-enable interactivity for just this subtree. */
.tp-photo-flyer #tp-pricing-build {
  pointer-events: auto;
}
.tp-photo-flyer-photo {
  flex-shrink: 0;
  width: 100%;
  overflow: hidden;
  border: 5px solid #fff;
  /* Matches .tp-hero-portrait's own radius. The outer .tp-photo-flyer also
     gets border-radius:32px (set inline by initPhotoMorph, matching this
     value) to round the combined photo+build unit as #tp-pricing-build
     grows beneath the photo — but that outer radius only wraps the OUTER
     box's own corners, which move further down as the build grows. Without
     its own radius here, the photo's bottom corners would go unrounded
     (square) as soon as any build height exists, even though its top
     corners (flush with the outer's top) stay rounded via the outer clip. */
  border-radius: 32px;
  padding: 15px;
}
.tp-photo-flyer-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 20px;
}

/* ============ SIMILAR TUTORS (livewire/components/similar-tutors.blade.php) ============
   Card itself is the shared <x-front.mentor-card> component (.scx-mentors-*,
   scrollix-sections.css, loaded sitewide) — no card-specific CSS lives here
   anymore. .tp-similar-grid is just this section's own grid container,
   sized to fit that shared card's own dimensions (it has no fixed width of
   its own — it fills whatever column width this grid gives it). */

.tp-similar-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
}
@media (max-width: 1300px) {
  .tp-similar-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 1100px) {
  .tp-similar-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 680px) {
  .tp-similar-grid {
    grid-template-columns: 1fr;
  }
}

/* ============ FINAL CTA ============ */

.tp-final-cta {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  text-align: left;
  background: #fff;
  border-radius: 32px;
  padding: 24px;
  box-shadow: 0 0 0 1px #d1d1d1;
}
@media (min-width: 810px) {
  .tp-final-cta {
    grid-template-columns: 0.9fr 1.1fr;
    gap: 32px;
    padding: 32px;
  }
}
.tp-final-cta-left {
  display: flex;
  flex-direction: column;
  padding: 8px;
}
.tp-final-cta-mentor {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.tp-final-cta-mentor img {
  width: 48px;
  height: 48px;
  border-radius: 999px;
  object-fit: cover;
  flex-shrink: 0;
}
.tp-final-cta-mentor h3 {
  font-family: "Capriola", sans-serif;
  font-size: 20px;
  font-weight: 700;
  color: #020202;
  margin: 0;
  overflow-wrap: break-word;
}
.tp-final-cta-text {
  font-size: 16px;
  line-height: 1.55;
  color: #4a4a4a;
  max-width: 340px;
  margin: 0 0 24px;
}
.tp-final-cta-left .am-btn {
  align-self: flex-start;
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 0 24px;
  border-radius: 999px;
  background: #020202;
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  border: none;
}
.tp-final-cta-left .am-btn:hover {
  background: #262626;
  color: #fff;
}
.tp-final-cta-left .am-btn i {
  display: none;
}
/* Used to be a padded pink info card (price + subject checklist); now
   holds the mentor's intro video instead (moved from the removed
   .tp-video section) — plain flex wrapper so .tp-video-wrap's own
   16:9/rounded/dark styling shows through untouched, sized to fill
   whatever width this grid column gets at each breakpoint. .tp-final-cta
   itself has no explicit height/align-items, so with .tp-final-cta-left
   already a column flex with its button pushed to the bottom via
   margin-top:auto, the left side naturally matches whatever height the
   video's aspect-ratio produces on the right, instead of leaving a
   mismatched gap. */
.tp-final-cta-right {
  display: flex;
}
.tp-final-cta-right .tp-video-wrap {
  width: 100%;
}

/* ============ MOBILE STICKY CONTACT CARD ============ */

.tp-mobile-sticky-card {
  display: none;
}
@media (max-width: 1023px) {
  /* Row layout: fixed photo on the left, a column (info block + CTA) filling
     the rest of the card's width to the right of it. */
  .tp-mobile-sticky-card {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 16px;
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: 16px;
    z-index: 40;
    background: #fff;
    border-radius: 20px;
    padding: 16px;
    box-shadow: 0 16px 40px -8px rgba(2, 2, 2, 0.22);
    opacity: 0;
    transform: translateY(28px);
    pointer-events: none;
    transition: opacity 320ms cubic-bezier(0.16, 1, 0.3, 1),
      transform 320ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .tp-mobile-sticky-card.is-visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  body.tp-mobile-card-visible {
    padding-bottom: var(--tp-mobile-card-h, 0px);
    transition: padding-bottom 320ms cubic-bezier(0.16, 1, 0.3, 1);
  }
}
.tp-mobile-card-photo {
  width: 120px;
  height: 120px;
  border-radius: 20px;
  overflow: hidden;
  flex-shrink: 0;
}
.tp-mobile-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tp-mobile-card-content {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: start;
  flex: 1;
  min-width: 0;
}
/* width:100% here (not left to .tp-mobile-card-content's align-items:start
   default) — otherwise this box sizes to its widest nowrap child's natural
   content width instead of the column's actual available width, so a long
   name/price never gets the chance to hit its own overflow:hidden and just
   pushes the info block wider than the card instead. */
.tp-mobile-card-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  min-width: 0;
  flex: 1;
}
.tp-mobile-card-name {
  display: block;
  font-size: 16px;
  font-weight: 700;
  color: #020202;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tp-mobile-card-meta {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  color: #4a4a4a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tp-mobile-card-meta .tp-star {
  color: #ffb100;
}
.tp-mobile-card-meta strong {
  color: #020202;
  font-weight: 700;
}
/* Plain inline flow, not flex — text-overflow:ellipsis only reliably
   truncates a single inline text run; splitting this line's price/
   separator/response text across flex children breaks the ellipsis (the
   line just clips mid-word with no "…" at very narrow widths instead). */
.tp-mobile-card-price {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #020202;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tp-mobile-card-price sup {
  font-size: 11px;
}
.tp-mobile-card-response-sep {
  margin: 0 5px;
  color: #8a8a8a;
}
.tp-mobile-card-response {
  font-weight: 500;
  color: #6b6b6b;
}
/* align-self:stretch (not the content column's own align-items:start) so
   the button spans the same width as the info block above it, rather than
   shrinking to fit its own "Book a session" label. */
.tp-mobile-card-cta {
  align-self: stretch;
  height: 44px;
  padding: 0 12px;
  font-size: 14.5px;
  font-weight: 700;
  border-radius: 999px;
  background: linear-gradient(38deg, #ffbcbc 0%, #ff6363 54.0541%);
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The button's width is tied to the info column beside the 120px photo
   (align-self:stretch above), which only leaves ~120px of room at the
   narrowest supported phones — enough for "Book a session" to wrap to 2
   lines at the base 14.5px size. Smaller text keeps it on one line instead. */
@media (max-width: 360px) {
  .tp-mobile-card-cta {
    font-size: 12.5px;
    padding: 0 8px;
  }
}

/* ============ Shared bits ============ */

.tp-star {
  color: #ffb100;
}

@media (prefers-reduced-motion: reduce) {
  .tp-photo-flyer {
    display: none !important;
  }
}

.am-reviews_wrap {
  padding: 0 !important;
}

.am-tooltip-text {
  width: max-content !important;
  letter-spacing: normal;
}

.am-similar-tutor .am-similaruser-btn {
  margin-top: 40px;
}

/* Bootstrap's default modal/backdrop z-index (1055/1050) sits well below
   this site's fixed header (scrollix-header.css: z-index:9999), so the
   guest-register-popup modal (and its backdrop) rendered underneath it —
   the nav bar/search row stayed visible and clickable on top of the
   form. .modal-backdrop is a single shared element Bootstrap appends
   wherever it likes in <body> (not necessarily adjacent to the modal
   that opened it, so a "#guest-register-popup + .modal-backdrop" sibling
   selector wouldn't reliably match) — targeted directly instead. Safe to
   do broadly here since this stylesheet only loads on the tutor-detail
   page: any other modal on this same page (e.g. the send-message popup,
   the sitewide toast/confirm modal from <x-popups>) has the identical
   fixed-header problem and benefits the same way. !important is needed
   to reliably beat Bootstrap's own rule regardless of stylesheet load
   order. */
.modal-backdrop {
  z-index: 10000 !important;
}
#guest-register-popup.modal {
  z-index: 10001 !important;
}
/* Side effect of the backdrop override above: the "Envoyer un message"
   modal (<livewire:pages.tutor.action.action>'s send-message popup) lives
   inside #tp-pricing-build, which sits inside .tp-sidebar-sticky once
   "docked" (see tutor-detail-page.js's forceDocked handling — the modal is
   now always force-docked out of .tp-photo-flyer before it's shown, so
   only this container needs the fix). .tp-sidebar-sticky's position:sticky
   creates its own stacking context, so the modal's own z-index:1055 only
   competed within THAT context, not against the backdrop's z-index:10000
   sitting directly on <body> — clicks landed on the backdrop instead of
   the modal's textarea. Only elevate while a modal is actually open.

   Scoped to body.tp-msg-modal-open specifically — NOT Bootstrap's own
   generic body.modal-open, which is added for ANY shown modal, including
   the guest-register-popup (a separate, body-level modal that is NOT
   nested inside .tp-sidebar-sticky and doesn't need this elevation at
   all). Using the generic class here elevated the sidebar above the
   guest modal's backdrop too — once the sidebar had actually docked into
   view, its real content (photo, Réserver/Contacter/heart buttons)
   rendered on top of the registration modal, unblurred, since the
   .tp-blur-sibling walk below is also only ever triggered for the
   message modal (buildEl.contains(e.target) in tutor-detail-page.js). A
   permanent (unconditional) elevation would let the sticky sidebar
   render above the fixed header (scrollix-header.css z-index:9999) while
   scrolling with no modal open at all. */
body.tp-msg-modal-open .tp-sidebar-sticky {
  z-index: 10002;
}
/* Background blur for the "Envoyer un message" modal, matching the mobile
   menu's blur (scrollix-header.css: html.nvg-panel-open blurs body content
   at filter:blur(8px), 300ms ease — same radius/timing here for visual
   consistency). backdrop-filter on .modal-backdrop alone computed
   correctly in automated testing but didn't actually render for a real
   user (GPU-compositing support gap, common in VMs/Remote Desktop — the
   menu's plain `filter` rendered fine in that same environment where
   backdrop-filter didn't). Kept below as a harmless progressive
   enhancement layered on top of the real fix: tutor-detail-page.js's
   show.bs.modal/hidden.bs.modal listeners walk up from the modal to
   <body> and add .tp-blur-sibling to every sibling at each level — the
   same content-filter technique as the menu, applied precisely to
   everything that isn't the modal's own ancestor chain (this naturally
   covers the book/message/favourite buttons and sidebar photo/price rows
   that visually peek out around the modal, matching what a real overlay
   should cover).

   Also darkens (brightness(0.55), matching .modal-backdrop's own
   rgba(0,0,0,0.5) tint mathematically: content*0.5 + black*0.5 ==
   content*0.5) — needed specifically because body.modal-open
   .tp-sidebar-sticky above elevates the WHOLE sticky sidebar (photo,
   price rows, buttons — not just the modal) to z-index:10002, above the
   backdrop's z-index:10000, so the sidebar card visually paints above
   the backdrop and its own dark tint can't reach it (confirmed: it was
   blurred but staying bright). Baking the darkening into this same
   per-element filter sidesteps that entirely — it darkens the element's
   own rendering directly, independent of stacking order, rather than
   relying on a separate overlay layer that stacking can hide behind. */
.tp-blur-sibling {
  filter: blur(8px) brightness(0.55);
  transition: filter 300ms ease;
  pointer-events: none;
}
body.tp-msg-modal-open .modal-backdrop {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: backdrop-filter 300ms ease, -webkit-backdrop-filter 300ms ease;
}
