/* ============================================================
 * v26 — Product Detail (products/show.php) per-view stylesheet
 * ------------------------------------------------------------
 * Loaded only by app/Views/v26/products/show.php. Every class below is a
 * genuine primitive that base.css does not provide; all color comes from
 * theme tokens (no raw hex) so light/dark + themes keep working. Justifications
 * are inline per group. If any of these recurs in a second view, promote it to
 * base.css and delete the copy here.
 * ============================================================ */

/* Tailwind's .animate-spin is used by the REUSED legacy payment/calendar
 * partials (spinners) but v26 ships no Tailwind — define the animation so
 * those spinners actually spin on this page. */
.animate-spin { animation: ps-spin 1s linear infinite; }
@keyframes ps-spin { to { transform: rotate(360deg); } }

/* JS-compat: the reused legacy course/booking partials (and this view's own
 * full-width action-button) express full width with Tailwind's .w-full, which
 * v26 does not ship. Define it here so those sat-btn CTAs span their column. */
.w-full { width: 100% !important; }

/* base.css's .s-card--flat uses --bg-secondary, which in the default theme
 * (#f7f7f7 vs. a #ffffff page) is only ~1% darker than white — the "flat
 * panel" reads as invisible against the page background instead of as a
 * recessed card. Override to --bg-tertiary, scoped to this page only (this
 * stylesheet loads nowhere else) — every .s-card--flat use on THIS page
 * (description panel, practitioner card, rating-summary sub-box) gets the
 * more visible tone; other v26 views keep base.css's subtler default. */
.s-card--flat { background: var(--bg-tertiary); }

/* base.css collapses .s-cols to an even 2-column grid between 640-900px
 * (repeat(2, 1fr)) — a reasonable default for card grids, but wrong here:
 * below 900px it squeezes the hero image, the 7-column calendar, and the
 * tabs into a half-width main column instead of stacking. Override to a
 * full single-column stack at the same 900px cutoff base.css uses, scoped
 * to this page only. */
@media (max-width: 900px) {
  .s-cols { grid-template-columns: 1fr; }
}

/* ── Hero gallery + image-overlay controls (base has no media/overlay) ── */
.ps-hero__media {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-secondary);
  margin-bottom: var(--s-space-5);
}
.ps-hero__img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 26rem;
  object-fit: cover;
}
.ps-hero__tl { position: absolute; top: var(--s-space-3); left: var(--s-space-3); }
/* Solid brand pill (vs. the tinted .s-chip--brand used elsewhere) — scoped to
 * the hero overlay position only, so the shared chip style stays untouched. */
.ps-hero__tl .s-chip {
  background: var(--brand-primary); color: var(--text-inverse); border-color: transparent;
  text-transform: uppercase; letter-spacing: .03em; font-weight: 700;
}
.ps-hero__tr {
  position: absolute; top: var(--s-space-3); right: var(--s-space-3);
  display: flex; gap: var(--s-space-2);
}
.ps-icon-round {
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border: none; border-radius: var(--radius-pill);
  background: var(--bg-primary); color: var(--text-secondary);
  box-shadow: var(--shadow-md); font-size: 1.125rem;
  cursor: pointer; text-decoration: none;
  transition: color var(--s-transition), background var(--s-transition);
}
.ps-icon-round:hover { color: var(--brand-primary); }

/* Avatars: renderAvatar() emits Tailwind size classes (w-16 h-16 …) that carry
 * no size without Tailwind — size them within this view's contexts. */
.ps-avatar { display: inline-block; flex-shrink: 0; }
.ps-avatar img { display: block; border-radius: var(--radius-pill); object-fit: cover; }
.ps-avatar--md img { width: 3rem;   height: 3rem; }
.ps-avatar--lg img { width: 4rem;   height: 4rem; }

/* Hero title — heavier + brand-toned than the default .s-main h1. */
#ps-title { font-weight: 800; color: var(--brand-primary); letter-spacing: -0.01em; }

/* ── Description/Reviews tabs (bottom, full-width — see .ps-tabs-section) ── */
.ps-tabs-section { margin-top: var(--s-space-6); }
.ps-tabs {
  display: flex; gap: var(--s-space-2);
  border-bottom: 1px solid var(--border-secondary);
  margin-bottom: var(--s-space-5);
}
.ps-tab {
  padding: var(--s-space-3) var(--s-space-4);
  margin-bottom: -1px;
  border: none; border-bottom: 2px solid transparent;
  background: none; cursor: pointer;
  font: inherit; font-weight: 600; font-size: var(--s-text-base);
  color: var(--text-tertiary);
  transition: color var(--s-transition), border-color var(--s-transition);
}
.ps-tab:hover { color: var(--brand-primary); }
.ps-tab.is-active { color: var(--brand-primary); border-bottom-color: var(--brand-primary); }

/* ── Price emphasis (calm, larger than body — like dashboard.css) ── */
.ps-price { display: flex; flex-direction: column; gap: 2px; text-align: right; }
.ps-price__amount { font-size: 1.75rem; font-weight: 800; color: var(--brand-primary); line-height: 1.1; }
.ps-price__label  { font-size: var(--s-text-xs); color: var(--text-tertiary); }

/* ── Compact hero meta line: rating + (course-only) lessons/language ── */
.ps-meta-row {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--s-space-2); font-size: var(--s-text-sm); color: var(--text-tertiary);
}
.ps-meta-rating { display: inline-flex; align-items: center; gap: 4px; color: var(--text-secondary); font-weight: 600; }
.ps-meta-rating i { color: var(--brand-primary); }
.ps-meta-dot { color: var(--text-quaternary); }

/* ── Star ratings (authored rows) — amber is not a semantic theme token, map
 *    it to --warning; empty stars fall to the border tone. ── */
.ps-stars { display: inline-flex; gap: 1px; color: var(--warning); }
.ps-stars i.ps-star-off { color: var(--border-primary); }

/* ── Reviews: rating summary + review rows ── */
.ps-rating-summary { display: flex; gap: var(--s-space-5); align-items: center; flex-wrap: wrap; }
.ps-rating-big { font-size: 2.5rem; font-weight: 800; color: var(--text-primary); line-height: 1; }
.ps-breakdown { flex: 1; min-width: 12rem; display: flex; flex-direction: column; gap: var(--s-space-2); }
.ps-breakdown__row { display: flex; align-items: center; gap: var(--s-space-2); font-size: var(--s-text-xs); color: var(--text-tertiary); }
.ps-breakdown__row .s-progress { flex: 1; }
.ps-review { display: flex; gap: var(--s-space-3); padding: var(--s-space-4) 0; border-top: 1px solid var(--border-secondary); }
.ps-review:first-child { border-top: 0; padding-top: 0; }
.ps-review__body { flex: 1; min-width: 0; }
.ps-review__name { font-weight: 600; color: var(--text-primary); text-decoration: none; }
.ps-review__name:hover { color: var(--brand-primary); }
.ps-response {
  margin-top: var(--s-space-3); padding: var(--s-space-3);
  border-radius: var(--radius-md); background: var(--bg-secondary);
  border-left: 3px solid var(--brand-primary);
}

/* ── Seller card ── */
.ps-seller-head { display: flex; gap: var(--s-space-3); align-items: flex-start; }
.ps-seller-msg {
  margin-left: auto; flex-shrink: 0;
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border: 1px solid var(--border-primary); border-radius: var(--radius-pill);
  background: var(--bg-primary); color: var(--brand-primary);
  cursor: pointer; text-decoration: none; font-size: 1.125rem;
  transition: background var(--s-transition);
}
.ps-seller-msg:hover { background: var(--primary-50); }
/* This card is the flat/gray (.s-card--flat) variant, so its heading and the
 * per-stat tiles need explicit contrast treatment the default white card
 * doesn't: brand-green heading, and WHITE stat tiles (not gray — they'd
 * disappear against the card's own gray background otherwise). */
#ps-seller-title { color: var(--brand-primary); font-size: 1.0625rem; margin-bottom: var(--s-space-5); }
.ps-seller-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-space-2); text-align: center; margin: var(--s-space-4) 0; }
.ps-seller-stats > div { background: var(--bg-primary); border-radius: var(--radius-md); padding: var(--s-space-3) var(--s-space-1); }
.ps-seller-stats__num { font-size: var(--s-text-lg); font-weight: 700; color: var(--brand-primary); }
.ps-seller-stats__label { font-size: var(--s-text-xs); color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.04em; }
.ps-seller-facts { display: flex; flex-direction: column; gap: var(--s-space-2); font-size: var(--s-text-sm); color: var(--text-tertiary); }
.ps-seller-facts i { color: var(--brand-primary); margin-right: .35rem; }

/* "View Full Profile" — full pill, brand-outlined at rest (the shared
 * .sat-btn--secondary is neutral-at-rest/brand-on-hover everywhere else;
 * scoped override here, not a change to the shared button style), and an
 * explicit white fill since it sits on this card's gray background. */
.ps-seller-cta { margin-top: var(--s-space-4); }
.ps-seller-cta .sat-btn--secondary {
  border-radius: var(--radius-pill); border-width: 1.5px;
  border-color: var(--brand-primary); color: var(--brand-primary);
  background: var(--bg-primary);
}

/* ── Booking panel: restyle the REUSED legacy booking-calendar partial's CTA +
 *    legend in v26 (the partial ships Tailwind utilities v26 does not load).
 *    Scoped to .booking-calendar-wrapper so nothing leaks. ── */
.booking-calendar-wrapper .mt-4 > a,
.booking-calendar-wrapper #book-session-btn {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; min-height: var(--s-control-h);
  padding: var(--s-space-3) var(--s-space-5);
  border: none; border-radius: var(--radius-md);
  background: var(--brand-primary); color: var(--text-inverse);
  font: inherit; font-weight: 600; font-size: var(--s-text-base);
  cursor: pointer; text-decoration: none;
  transition: background var(--s-transition);
}
.booking-calendar-wrapper .mt-4 > a:hover,
.booking-calendar-wrapper #book-session-btn:hover:not(:disabled) { background: var(--brand-primary-hover); }
.booking-calendar-wrapper #book-session-btn:disabled { opacity: .5; cursor: not-allowed; }
/* legend swatches (token-safe) */
.booking-calendar-wrapper .w-4.h-4 { border-radius: var(--radius-md); }
.booking-calendar-wrapper .w-4.bg-white { background: var(--bg-primary); border: 1px solid var(--border-primary); }
.booking-calendar-wrapper .w-4.bg-gray-200 { background: var(--bg-tertiary); }

/* The CTA + legend above were the only part of this partial bridged so far —
 * everything else (header row, loading spinner, selected-slot box) was still
 * raw Tailwind classes with no definition, which is why the header read as
 * cramped/unspaced. Same utility-shim approach as .course-purchase-panel
 * below: only layout/spacing/sizing needs a real rule, colors already resolve
 * via theme-system.css. */
.booking-calendar-wrapper .flex { display: flex; }
.booking-calendar-wrapper .items-center { align-items: center; }
.booking-calendar-wrapper .justify-between { justify-content: space-between; }
.booking-calendar-wrapper .justify-center { justify-content: center; }
.booking-calendar-wrapper .flex-wrap { flex-wrap: wrap; }
.booking-calendar-wrapper .gap-2 { gap: var(--s-space-2); }
.booking-calendar-wrapper .gap-4 { gap: var(--s-space-4); }
.booking-calendar-wrapper .mb-1 { margin-bottom: var(--s-space-1); }
.booking-calendar-wrapper .mb-2 { margin-bottom: var(--s-space-2); }
.booking-calendar-wrapper .mb-4 { margin-bottom: var(--s-space-4); }
.booking-calendar-wrapper .mt-1 { margin-top: var(--s-space-1); }
.booking-calendar-wrapper .mt-4 { margin-top: var(--s-space-4); }
.booking-calendar-wrapper .mr-1 { margin-right: var(--s-space-1); }
.booking-calendar-wrapper .mr-2 { margin-right: var(--s-space-2); }
.booking-calendar-wrapper .p-4 { padding: var(--s-space-4); }
.booking-calendar-wrapper .mx-auto { margin-left: auto; margin-right: auto; }
.booking-calendar-wrapper .h-full { height: 100%; }
.booking-calendar-wrapper .h-8 { height: 2rem; }
.booking-calendar-wrapper .w-8 { width: 2rem; }
.booking-calendar-wrapper .text-center { text-align: center; }
.booking-calendar-wrapper .text-lg { font-size: var(--s-text-lg); }
.booking-calendar-wrapper .text-sm { font-size: var(--s-text-sm); }
.booking-calendar-wrapper .font-semibold { font-weight: 600; }
.booking-calendar-wrapper .font-medium { font-weight: 500; }
.booking-calendar-wrapper .font-bold { font-weight: 700; }
.booking-calendar-wrapper .font-normal { font-weight: 400; }
.booking-calendar-wrapper .opacity-90 { opacity: .9; }
.booking-calendar-wrapper .underline { text-decoration: underline; }
.booking-calendar-wrapper .underline:hover { opacity: .8; }
.booking-calendar-wrapper .rounded-xl { border-radius: var(--radius-md); }
.booking-calendar-wrapper .rounded-full { border-radius: var(--radius-pill); }
.booking-calendar-wrapper .border { border-width: 1px; border-style: solid; }
.booking-calendar-wrapper .border-b-2 { border-bottom-width: 2px; border-bottom-style: solid; }

/* Mobile: calendar-grid.css + the calendar JS always render 7 columns; below
 * 640px let the grid keep a comfortable tap width and scroll horizontally
 * inside its own box rather than crush each column (calendar-grid.css frozen). */
@media (max-width: 640px) {
  .booking-calendar-wrapper .booking-calendar-container { overflow-x: auto !important; -webkit-overflow-scrolling: touch; }
  .booking-calendar-wrapper .satya-calendar-grid { min-width: 32rem; }
}

/* ── Course purchase panel: restyle the REUSED legacy course-purchase-panel
 *    partial (Tailwind-authored; kept verbatim as "the payments reference" —
 *    same bridge pattern as .booking-calendar-wrapper above). Colors already
 *    resolve globally via theme-system.css utility classes (.text-tertiary,
 *    .bg-primary, .text-brand-primary, focus:ring-brand-primary, etc. are
 *    theme-system classes, not Tailwind) — only layout/spacing/sizing needs a
 *    real declaration here. Scoped to .course-purchase-panel so nothing leaks
 *    into other v26 views. ── */
.course-purchase-panel .block { display: block; }
.course-purchase-panel .flex { display: flex; }
.course-purchase-panel .inline-flex { display: inline-flex; }
.course-purchase-panel .items-center { align-items: center; }
.course-purchase-panel .items-start { align-items: flex-start; }
.course-purchase-panel .items-baseline { align-items: baseline; }
.course-purchase-panel .justify-center { justify-content: center; }
.course-purchase-panel .flex-1 { flex: 1 1 0%; }
.course-purchase-panel .flex-shrink-0 { flex-shrink: 0; }
.course-purchase-panel .gap-1\.5 { gap: 0.375rem; }
.course-purchase-panel .gap-2 { gap: var(--s-space-2); }
.course-purchase-panel .space-y-1 > * + * { margin-top: var(--s-space-1); }

.course-purchase-panel .mb-1 { margin-bottom: var(--s-space-1); }
.course-purchase-panel .mb-2 { margin-bottom: var(--s-space-2); }
.course-purchase-panel .mb-3 { margin-bottom: var(--s-space-3); }
.course-purchase-panel .mb-4 { margin-bottom: var(--s-space-4); }
.course-purchase-panel .mt-1 { margin-top: var(--s-space-1); }
.course-purchase-panel .mt-2 { margin-top: var(--s-space-2); }
.course-purchase-panel .mt-3 { margin-top: var(--s-space-3); }
.course-purchase-panel .mt-4 { margin-top: var(--s-space-4); }
.course-purchase-panel .mr-1 { margin-right: var(--s-space-1); }

.course-purchase-panel .p-2 { padding: var(--s-space-2); }
.course-purchase-panel .p-3 { padding: var(--s-space-3); }
.course-purchase-panel .p-4 { padding: var(--s-space-4); }
.course-purchase-panel .p-6 { padding: var(--s-space-5); }
.course-purchase-panel .px-4 { padding-left: var(--s-space-4); padding-right: var(--s-space-4); }
.course-purchase-panel .py-4 { padding-top: var(--s-space-4); padding-bottom: var(--s-space-4); }

@media (min-width: 640px) {
  .course-purchase-panel .sm\:px-6 { padding-left: var(--s-space-5); padding-right: var(--s-space-5); }
  .course-purchase-panel .sm\:py-6 { padding-top: var(--s-space-5); padding-bottom: var(--s-space-5); }
  .course-purchase-panel .sm\:p-4 { padding: var(--s-space-4); }
  .course-purchase-panel .sm\:p-8 { padding: var(--s-space-6); }
}

.course-purchase-panel .text-xs { font-size: var(--s-text-xs); }
.course-purchase-panel .text-sm { font-size: var(--s-text-sm); }
.course-purchase-panel .text-xl { font-size: 1.25rem; }
.course-purchase-panel .text-2xl { font-size: 1.5rem; }
.course-purchase-panel .text-6xl { font-size: 3.75rem; }
.course-purchase-panel .font-bold { font-weight: 700; }
.course-purchase-panel .text-center { text-align: center; }

.course-purchase-panel .border { border-width: 1px; border-style: solid; }
.course-purchase-panel .rounded { border-radius: var(--radius-sm); }
/* Radii below match the analogous Stripe-box / modal-dialog treatment the
 * booking modal already uses further down this file (.ps-card-box, .ps-modal__dialog). */
.course-purchase-panel .rounded-lg,
.course-purchase-panel .rounded-xl { border-radius: var(--radius-md); }
.course-purchase-panel .rounded-2xl { border-radius: var(--radius-lg); }

.course-purchase-panel .cursor-pointer { cursor: pointer; }
.course-purchase-panel .hover\:underline:hover { text-decoration: underline; }
.course-purchase-panel .pointer-events-none { pointer-events: none; }
.course-purchase-panel .opacity-60 { opacity: .6; }

/* Success modal: fixed full-screen overlay (JS toggles .hidden on #course-success-modal). */
.course-purchase-panel .fixed { position: fixed; }
.course-purchase-panel .absolute { position: absolute; }
.course-purchase-panel .relative { position: relative; }
.course-purchase-panel .inset-0 { inset: 0; }
.course-purchase-panel .z-\[70\] { z-index: 70; }
.course-purchase-panel .bg-black\/60 { background: var(--s-overlay); }
.course-purchase-panel .backdrop-blur-sm { backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.course-purchase-panel .shadow-2xl { box-shadow: var(--shadow-lg); }
.course-purchase-panel .max-w-md { max-width: 28rem; }

/* EU withdrawal-waiver checkbox has no forms-reset without Tailwind either way
 * (the partial never ships one); the accent color is a harmless, real upgrade. */
.course-purchase-panel input[type="checkbox"] { accent-color: var(--brand-primary); }

/* Eyebrow label above the panel's price. */
.ps-eyebrow {
  font-size: var(--s-text-xs); font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--brand-primary); margin-bottom: var(--s-space-1);
}

/* Purchase-panel CTAs (course enrol/buy states) — full pill instead of the
 * shared .sat-btn's default radius-md.
 * Scoped to this class only; every other button on the site keeps its
 * normal rounded-rectangle shape. */
.ps-pill-cta { border-radius: var(--radius-pill); }

/* Appointment "Book a session" card: authored with the same Tailwind-style
 * utility classes as .course-purchase-panel (eyebrow/price/bullets), but
 * this card isn't wrapped in that class, so those bridge rules didn't apply
 * — margins/gaps were silently no-ops, which is why it read as cramped. */
.ps-appt-panel .flex { display: flex; }
.ps-appt-panel .items-center { align-items: center; }
.ps-appt-panel .items-baseline { align-items: baseline; }
.ps-appt-panel .gap-2 { gap: var(--s-space-2); }
.ps-appt-panel .mb-1 { margin-bottom: var(--s-space-1); }
.ps-appt-panel .mb-2 { margin-bottom: var(--s-space-2); }
.ps-appt-panel .mb-4 { margin-bottom: var(--s-space-4); }
.ps-appt-panel .text-sm { font-size: var(--s-text-sm); }

/* ── Booking confirmation modal (base.css has no modal primitive) ── */
.ps-modal {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-space-4); background: var(--s-overlay);
}
.ps-modal__dialog {
  display: flex; flex-direction: column;
  width: 100%; max-width: 30rem;
  max-height: calc(100vh - 2rem); max-height: calc(100dvh - 2rem);
  overflow: hidden;
  background: var(--bg-primary); border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.ps-modal__head { flex-shrink: 0; padding: var(--s-space-4) var(--s-space-5); border-bottom: 1px solid var(--border-secondary); }
.ps-modal__head h3 { font-size: var(--s-text-lg); font-weight: 700; color: var(--text-primary); }
.ps-modal__body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--s-space-5); display: flex; flex-direction: column; gap: var(--s-space-4); }
.ps-modal__foot { flex-shrink: 0; display: flex; gap: var(--s-space-3); padding: var(--s-space-4) var(--s-space-5); border-top: 1px solid var(--border-secondary); background: var(--bg-secondary); }
.ps-modal__close { margin-left: auto; }
.ps-field-label { font-size: var(--s-text-xs); color: var(--text-tertiary); margin-bottom: 2px; }
.ps-field-value { font-weight: 600; color: var(--text-primary); }
.ps-modal__price { font-size: 1.5rem; font-weight: 800; color: var(--brand-primary); }

/* Payment method chooser — Stripe first + pre-selected (contract §12).
 * JS toggles `.selected` on the label + `.hidden` on the dot. */
.ps-pay-list { display: flex; flex-direction: column; gap: var(--s-space-2); }
.ps-pay {
  display: flex; align-items: center; gap: var(--s-space-3);
  padding: var(--s-space-3); border: 1px solid var(--border-primary);
  border-radius: var(--radius-md); cursor: pointer;
  transition: border-color var(--s-transition), background var(--s-transition);
}
.ps-pay.selected { border-color: var(--brand-primary); background: var(--primary-50); }
.ps-pay__ring {
  flex-shrink: 0; width: 1.25rem; height: 1.25rem;
  border: 2px solid var(--border-primary); border-radius: var(--radius-pill);
  display: grid; place-items: center;
}
.ps-pay.selected .ps-pay__ring { border-color: var(--brand-primary); }
.ps-pay .payment-dot { width: .625rem; height: .625rem; border-radius: var(--radius-pill); background: var(--brand-primary); }
.ps-pay__body { flex: 1; min-width: 0; }
.ps-pay__title { font-weight: 600; color: var(--text-primary); font-size: var(--s-text-sm); }
.ps-pay__desc { font-size: var(--s-text-xs); color: var(--text-tertiary); }
.ps-pay__warn { display: flex; align-items: center; gap: .35rem; margin-top: 2px; font-size: var(--s-text-xs); color: var(--warning); }
.ps-pay__icon { flex-shrink: 0; font-size: 1.25rem; color: var(--brand-primary); }
.ps-pay__icon--muted { color: var(--text-tertiary); }

/* Stripe card mount + discount + applied-discount box */
.ps-card-box { padding: var(--s-space-4); border: 1px solid var(--border-primary); border-radius: var(--radius-md); background: var(--bg-secondary); }
.ps-card-field { padding: var(--s-space-3); border: 1px solid var(--border-primary); border-radius: var(--radius-md); background: var(--bg-primary); }
.ps-discount-row { display: flex; gap: var(--s-space-2); }
.ps-discount-row .s-input { text-transform: uppercase; }
.ps-strike { text-decoration: line-through; }
