/* ==========================================================================
   Testimonials page - loaded only on /testimonials
   Template: testimonials.php | Behaviour: assets/js/testimonials.js | Data: data/testimonials.json

   Sections (search for the banner text):
     Shared helpers      quote marks, avatars, ratings
     1. Hero             testimonial wall
     2. Featured stories one large + supporting stories
     3. Explorer         filters, masonry gallery, read more, empty state
     4. Spotlight        story carousel
     5. Final CTA
     Responsive / Reduced motion

   All classes start with "ts-" so nothing here affects another page.
   ========================================================================== */

/* ---------- Shared helpers ---------- */
.ts-h2 { font-size: clamp(1.9rem, 3.8vw, 3.1rem); line-height: 1.05; letter-spacing: -.04em; font-weight: 800; color: var(--text-l); text-wrap: balance; margin: 0; }
.ts-h2 span { color: var(--green-ink); } .ts-h2.on-dark { color: #fff; } .ts-h2.on-dark span { color: var(--green); }
.ts-sec-head { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: clamp(16px, 4vw, 56px); align-items: end; margin-bottom: clamp(28px, 4vw, 52px); }
.ts-sec-sub { margin: 0; color: var(--mute-l); font-size: 1.04rem; line-height: 1.7; } .ts-sec-sub.on-dark { color: var(--mute-d); }
.ts-big-quote { display: block; font: 800 clamp(5rem, 9vw, 8rem)/.7 Georgia, 'Times New Roman', serif; color: var(--green); opacity: .9; user-select: none; }
.ts-avatar { flex: none; width: 56px; height: 56px; border-radius: 50%; object-fit: cover; border: 2px solid rgba(126, 217, 87, .6); } .ts-avatar--lg { width: 68px; height: 68px; } .ts-avatar--sm { width: 36px; height: 36px; border-width: 1.5px; }
.ts-avatar--letter { display: grid; place-items: center; background: linear-gradient(135deg, #7ED957, #2f7d17); color: #07120a; font-weight: 800; font-size: 1.2rem; }
.ts-rate { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 6px 0 0; font-size: .78rem; color: var(--mute-l); } .ts-rate .stars { display: inline-flex; gap: 2px; } .ts-rate .star { width: 15px; height: 15px; fill: rgba(8, 8, 8, .15); } .ts-rate .star.on, .ts-rate .star.half { fill: #e0a000; }
.dark .ts-rate, .ts-panel .ts-rate { color: var(--mute-d); } .dark .ts-rate .star, .ts-panel .ts-rate .star { fill: rgba(255, 255, 255, .22); } .dark .ts-rate .star.on, .dark .ts-rate .star.half, .ts-panel .ts-rate .star.on, .ts-panel .ts-rate .star.half { fill: #f2b01e; }

/* ==========================================================================
   1. Hero: testimonial wall
   ========================================================================== */
.ts-hero { position: relative; display: flex; align-items: center; overflow: hidden; min-height: min(100svh, 960px); padding: calc(var(--header-h) + clamp(34px, 5vw, 70px)) 0 clamp(90px, 9vw, 130px); background: radial-gradient(100% 100% at 85% 100%, #0f1a13, var(--black) 62%); }
.ts-hero-bg { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; } .ts-hero-glow { position: absolute; width: 640px; height: 640px; right: -8%; top: 14%; border-radius: 50%; background: radial-gradient(closest-side, rgba(126, 217, 87, .2), transparent); animation: tsGlow 3s ease-out both; } @keyframes tsGlow { from { opacity: 0; } }
.ts-hero-grid { display: grid; grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); gap: clamp(30px, 5vw, 70px); align-items: center; width: 100%; }
.ts-label { display: inline-flex; align-items: center; gap: 12px; font-size: .76rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: var(--green); margin: 0 0 22px; } .ts-label::before { content: ''; width: 34px; height: 1.5px; background: currentColor; }
.ts-title { font-size: clamp(2.2rem, 4.4vw, 3.9rem); line-height: 1.04; letter-spacing: -.045em; font-weight: 800; color: #fff; }
.ts-title .ln { display: block; overflow: hidden; padding-bottom: .14em; margin-bottom: -.14em; } .ts-title .lni { display: inline-block; will-change: transform; }
.ts-title em { font-style: normal; background: linear-gradient(100deg, #7ED957 10%, #d3f7bd 90%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.ts-rule { display: block; width: 130px; height: 2px; margin: 26px 0 4px; background: linear-gradient(90deg, var(--green), transparent); transform-origin: left; animation: tsRule 1.5s .3s var(--ease) both; } @keyframes tsRule { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.ts-lead { margin-top: 22px; } .ts-ctas { margin-top: 30px; }
.ts-wall { position: relative; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.ts-panel { position: relative; padding: 20px 20px 18px; border-radius: 20px; background: linear-gradient(160deg, rgba(255, 255, 255, .09), rgba(255, 255, 255, .03)); border: 1px solid rgba(255, 255, 255, .14); backdrop-filter: blur(10px); box-shadow: 0 30px 56px -30px rgba(0, 0, 0, .85); color: #fff; transition: transform .6s var(--ease), border-color .4s; }
.ts-panel--1 { margin-top: 36px; } .ts-panel--3 { margin-top: 22px; } .ts-panel .ts-rate time { display: none; }
.ts-panel:hover { transform: translateY(-4px); border-color: rgba(126, 217, 87, .5); }
.ts-panel .ts-quote-mark { display: block; font: 800 3.2rem/.6 Georgia, serif; color: var(--green); margin-bottom: 8px; animation: tsMark 4s ease-in-out infinite alternate; } @keyframes tsMark { from { opacity: .55; } to { opacity: 1; } }
.ts-panel p { margin: 0 0 14px; font-size: .92rem; line-height: 1.55; color: #e4ece4; }
.ts-panel footer { display: flex; align-items: center; gap: 10px; } .ts-panel footer b { display: block; font-size: .84rem; } .ts-panel footer small { color: var(--mute-d); font-size: .72rem; }
.ts-panel.is-empty { border-style: dashed; background: rgba(255, 255, 255, .03); } .ts-panel.is-empty small { display: block; margin-top: 14px; color: var(--mute-d); font-size: .72rem; }
.ts-skel { display: block; height: 8px; border-radius: 99px; background: rgba(255, 255, 255, .12); margin: 9px 0; } .ts-skel.w1 { width: 92%; } .ts-skel.w2 { width: 76%; } .ts-skel.w3 { width: 54%; }

/* ==========================================================================
   2. Featured client stories
   ========================================================================== */
.ts-feature-grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: clamp(18px, 3vw, 36px); align-items: stretch; }
.ts-feature-grid--2 .ts-story--small, .ts-feature-grid--1 .ts-story--note { grid-column: 2; }
.ts-feature-grid--3 .ts-story--small:nth-of-type(2) { grid-column: 2; grid-row: 1; } .ts-feature-grid--3 .ts-story--small:nth-of-type(3) { grid-column: 2; grid-row: 2; }
.ts-feature-grid--3 .ts-story--main, .ts-feature-grid--2 .ts-story--main, .ts-feature-grid--1 .ts-story--main { grid-column: 1; grid-row: 1 / span 2; }
.ts-story { position: relative; display: flex; flex-direction: column; padding: clamp(24px, 3vw, 42px); border-radius: 26px; background: var(--soft); border: 1px solid var(--line-l); transition: border-color .4s, box-shadow .4s, transform .4s var(--ease); overflow: hidden; }
.ts-story:hover { border-color: rgba(47, 125, 23, .5); box-shadow: 0 30px 50px -34px rgba(27, 110, 0, .45); transform: translateY(-3px); }
.ts-story--main { background: var(--black); color: #fff; border-color: var(--black); } .ts-story--main:hover { border-color: var(--green); }
.ts-story .ts-big-quote { margin-bottom: 14px; } .ts-story--small .ts-big-quote, .ts-story--note .ts-big-quote { font-size: 4.4rem; color: var(--green-ink); }
.ts-story-service { margin: 0 0 14px; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; font-weight: 800; } .ts-story-service a { color: var(--green-ink); border-bottom: 1px solid rgba(47, 125, 23, .35); } .ts-story--main .ts-story-service a, .ts-slide .ts-story-service a { color: var(--green); border-color: rgba(126, 217, 87, .4); }
.ts-story blockquote { margin: 0; flex: 1; } .ts-story blockquote p { margin: 0; font-size: clamp(1.05rem, 1.5vw, 1.2rem); line-height: 1.7; } .ts-story--main blockquote p { font-size: clamp(1.25rem, 2.1vw, 1.75rem); line-height: 1.55; letter-spacing: -.01em; color: #fff; }
.ts-divider { display: block; width: 0; height: 2px; margin: 26px 0 22px; background: linear-gradient(90deg, var(--green), transparent); transition: width 1s var(--ease) .2s; } .ts-story.is-in .ts-divider, .no-anim .ts-divider { width: 140px; }
.ts-story footer { display: flex; align-items: center; gap: 14px; margin-top: 22px; } .ts-story--main footer { margin-top: 0; } .ts-story footer strong { display: block; font-size: 1.05rem; }
.ts-story--main .ts-avatar { clip-path: circle(0 at 50% 50%); transition: clip-path 1s var(--ease) .3s; } .ts-story--main.is-in .ts-avatar, .no-anim .ts-story--main .ts-avatar { clip-path: circle(75% at 50% 50%); }
.ts-story--note { background: transparent; border-style: dashed; border-color: rgba(47, 125, 23, .4); justify-content: center; } .ts-story--note h3 { font-size: 1.4rem; letter-spacing: -.03em; } .ts-story--note p { margin: 10px 0 18px; color: var(--mute-l); } .ts-story--note .link-arrow { align-self: flex-start; }
.ts-empty-block { text-align: center; padding: 50px 20px; border-radius: 24px; border: 1px dashed rgba(47, 125, 23, .4); } .ts-empty-block p { margin: 10px 0 0; color: var(--mute-l); }

/* ==========================================================================
   3. Service-based testimonial explorer
   ========================================================================== */
.ts-explorer { background: radial-gradient(90% 70% at 50% 0%, #16211a, #0d120f 60%, var(--black)); }
.ts-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.ts-filter { display: inline-flex; align-items: center; gap: 9px; padding: 10px 16px; border-radius: 99px; font-size: .86rem; font-weight: 700; color: var(--text-d); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .15); transition: background .3s, color .3s, border-color .3s, transform .3s var(--ease); }
.ts-filter b { min-width: 22px; padding: 1px 7px; border-radius: 99px; font-size: .72rem; text-align: center; background: rgba(255, 255, 255, .12); } .ts-filter:hover { border-color: rgba(126, 217, 87, .6); transform: translateY(-2px); }
.ts-filter.is-on { background: var(--green); color: #07120a; border-color: var(--green); box-shadow: 0 10px 28px -10px rgba(126, 217, 87, .7); } .ts-filter.is-on b { background: rgba(7, 18, 10, .15); }
.ts-count { margin: 0 0 24px; font-size: .9rem; color: var(--mute-d); }
/* Testimonial rows: one horizontal card per testimonial (person on the left, quote on the right), numbered pages below. */
.ts-gallery { display: grid; gap: 16px; }
.ts-card { position: relative; display: grid; grid-template-columns: minmax(200px, 270px) minmax(0, 1fr); gap: clamp(18px, 3vw, 40px); align-items: center; padding: clamp(20px, 2.6vw, 30px) clamp(20px, 3vw, 36px); border-radius: 22px; background: linear-gradient(160deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .03)); border: 1px solid rgba(255, 255, 255, .13); color: #fff; transition: transform .4s var(--ease), border-color .4s, box-shadow .4s, opacity .45s; }
.ts-card::before { content: ""; position: absolute; left: 0; top: 22px; bottom: 22px; width: 3px; border-radius: 0 3px 3px 0; background: var(--green); opacity: .55; transition: opacity .3s; }
.ts-card:hover, .ts-card:focus-within { transform: translateY(-3px); border-color: var(--green); box-shadow: 0 0 40px -12px rgba(126, 217, 87, .5); } .ts-card:hover::before { opacity: 1; }
.ts-card.is-hidden { display: none; } .ts-card.is-entering { animation: tsCardIn .55s var(--ease) both; animation-delay: calc(var(--i, 0) * 60ms); } @keyframes tsCardIn { from { opacity: 0; transform: translateY(18px) scale(.98); } }
.ts-card-who { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 14px; align-items: center; } .ts-card-who .ts-avatar { grid-row: 1 / span 2; width: 64px; height: 64px; } .ts-card-who strong { display: block; font-size: 1.05rem; letter-spacing: -.01em; } .ts-card-who .ts-rate { grid-column: 1 / -1; margin-top: 10px; }
.ts-card-mark { position: absolute; right: clamp(18px, 3vw, 34px); top: 12px; font: 800 4.4rem/1 Georgia, serif; color: var(--green); opacity: .16; pointer-events: none; }
.ts-card-service { grid-column: 2; margin: 0; } .ts-card-service span { display: inline-block; padding: 3px 10px; border-radius: 99px; font-size: .64rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; color: var(--green); border: 1px solid rgba(126, 217, 87, .4); background: rgba(126, 217, 87, .08); transition: background .3s, color .3s; } .ts-card:hover .ts-card-service span { background: var(--green); color: #07120a; }
.ts-card-body { position: relative; min-width: 0; padding-left: clamp(0px, 2vw, 28px); padding-right: clamp(0px, 4vw, 56px); border-left: 1px solid rgba(255, 255, 255, .1); }
.ts-card-quote { margin: 0; } .ts-card-quote p { margin: 0; font-size: 1.02rem; line-height: 1.7; color: #e4ece4; }
.ts-card-quote.is-clamped p { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; } .ts-card.is-expanded .ts-card-quote.is-clamped p { display: block; -webkit-line-clamp: unset; }
.ts-more { margin: 10px 0 0; font-size: .84rem; font-weight: 700; color: var(--green); border-bottom: 1px solid rgba(126, 217, 87, .4); } .ts-more:hover { border-color: var(--green); }
.ts-empty { text-align: center; padding: clamp(36px, 6vw, 64px) 20px; border-radius: 24px; border: 1px dashed rgba(126, 217, 87, .4); background: rgba(255, 255, 255, .03); } .ts-empty[hidden] { display: none; } .ts-empty h3 { font-size: 1.3rem; color: #fff; letter-spacing: -.02em; } .ts-empty p { margin: 10px auto 20px; max-width: 46ch; color: var(--mute-d); }
.ts-pager { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; margin-top: 26px; } .ts-pager[hidden] { display: none; }
.ts-pager button { min-width: 42px; height: 42px; padding: 0 14px; border-radius: 99px; font-size: .9rem; font-weight: 700; color: var(--text-d); background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .18); transition: background .25s, color .25s, border-color .25s, transform .25s; } .ts-pager button:hover:not(:disabled) { border-color: var(--green); transform: translateY(-2px); }
.ts-pager button[aria-current="page"] { background: var(--green); color: #07120a; border-color: var(--green); } .ts-pager button:disabled { opacity: .35; cursor: default; } .ts-pager .ts-gap { color: var(--mute-d); padding: 0 2px; }

/* ==========================================================================
   4. Client feedback spotlight (carousel)
   ========================================================================== */
.ts-carousel { position: relative; }
.ts-track { position: relative; }
.ts-slide { display: none; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(24px, 5vw, 70px); align-items: center; padding: clamp(26px, 4vw, 56px); border-radius: 30px; background: var(--black); color: #fff; overflow: hidden; }
.ts-slide.is-active { display: grid; animation: tsSlideIn .7s var(--ease) both; } @keyframes tsSlideIn { from { opacity: 0; transform: translateX(24px); } }
.ts-slide .ts-big-quote { margin-bottom: 18px; }
.ts-slide blockquote { margin: 0; } .ts-slide blockquote p { margin: 0; font-size: clamp(1.2rem, 2.1vw, 1.7rem); line-height: 1.55; letter-spacing: -.01em; color: #fff; }
.ts-slide footer { display: flex; align-items: center; gap: 16px; margin-top: 28px; } .ts-slide footer strong { display: block; font-size: 1.1rem; } .ts-slide .ts-story-service { display: block; margin: 4px 0 0; }
.ts-slide-visual { position: relative; display: grid; gap: 14px; justify-items: center; }
.ts-visual-frame { width: 100%; max-width: 420px; aspect-ratio: 4 / 3; border-radius: 24px; padding: 8%; display: grid; place-items: center; background: radial-gradient(circle at 30% 25%, #1f3a24, #0c140e); border: 1px solid rgba(126, 217, 87, .35); box-shadow: 0 0 80px -26px rgba(126, 217, 87, .5); clip-path: inset(0 0 0 0 round 24px); } .ts-slide.is-active .ts-visual-frame { animation: tsMask .9s var(--ease) both; } @keyframes tsMask { from { clip-path: inset(0 100% 0 0 round 24px); } }
.ts-visual-frame .art { width: 100%; height: auto; max-height: 100%; }
.ts-visual-label { font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; font-weight: 700; color: var(--green); }
.ts-controls { display: flex; align-items: center; gap: 18px; margin-top: 22px; }
.ts-progress { flex: 1; height: 3px; border-radius: 3px; background: var(--line-l); overflow: hidden; } .ts-progress i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, var(--green-ink), var(--green)); transform: scaleX(var(--p, 0)); transform-origin: left; }
.ts-position { margin: 0; font-size: .86rem; font-weight: 700; color: var(--mute-l); } .ts-position span { color: var(--green-ink); }
.ts-buttons { display: flex; gap: 10px; }
.ts-ctrl { color: var(--text-l); border: 1px solid var(--line-l); background: #fff; } .ts-ctrl:hover { background: var(--black); color: var(--green); }

/* ==========================================================================
   5. Final call to action
   ========================================================================== */
.ts-cta { text-align: center; background: radial-gradient(70% 90% at 50% 100%, #12251a, var(--black) 70%); padding-block: clamp(96px, 13vw, 180px); }
.ts-cta-lines { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; opacity: .6; } .ts-cta-lines .marks text { font: 800 220px Georgia, serif; fill: rgba(126, 217, 87, .1); } .ts-cta-lines .lines path { stroke: var(--green); stroke-width: 1.4; stroke-opacity: .5; stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--d, 1)); }
.ts-cta-inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: 26px; } .ts-cta .eyebrow { justify-content: center; } .ts-cta .lead { margin: 0 auto; text-align: center; } .ts-cta .btn-row { justify-content: center; }
.ts-big { font-size: clamp(2.3rem, 5.4vw, 4.6rem); line-height: 1; letter-spacing: -.045em; font-weight: 800; color: #fff; max-width: 17ch; margin: 0 auto; text-wrap: balance; } .ts-big span { color: var(--green); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1100px) {
  .ts-card { grid-template-columns: minmax(180px, 220px) minmax(0, 1fr); }
  .ts-hero { min-height: 0; } .ts-hero-grid, .ts-feature-grid, .ts-slide, .ts-sec-head { grid-template-columns: minmax(0, 1fr); }
  .ts-feature-grid .ts-story--main, .ts-feature-grid .ts-story--small, .ts-feature-grid .ts-story--note { grid-column: 1 !important; grid-row: auto !important; }
}
@media (max-width: 640px) {
  .ts-wall { grid-template-columns: minmax(0, 1fr); gap: 12px; } .ts-panel--1, .ts-panel--2, .ts-panel--3 { margin-top: 0; } .ts-panel--2, .ts-panel--3 { display: none; }
  .ts-filters { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-right: -16px; padding: 4px 16px 6px 0; } .ts-filters::-webkit-scrollbar { display: none; } .ts-filter { flex: none; }
  .ts-card { grid-template-columns: minmax(0, 1fr); gap: 14px; padding: 22px 20px 20px 24px; } .ts-card-body { padding: 14px 0 0; border-left: 0; border-top: 1px solid rgba(255, 255, 255, .1); } .ts-card-who .ts-avatar { width: 52px; height: 52px; } .ts-card-mark { display: none; } .ts-pager button { min-width: 38px; height: 38px; padding: 0 11px; }
  .ts-controls { flex-wrap: wrap; } .ts-progress { flex-basis: 100%; order: 3; } .ts-buttons { margin-left: auto; }
  .ts-cta { padding-block: 76px; }
}
@media (hover: none) { .ts-filter:hover, .ts-card:hover, .ts-panel:hover, .ts-story:hover { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .ts-rule, .ts-hero-glow, .ts-panel .ts-quote-mark, .ts-card.is-entering, .ts-slide.is-active, .ts-slide.is-active .ts-visual-frame { animation: none !important; }
  .ts-divider { width: 140px; transition: none; } .ts-story--main .ts-avatar { clip-path: none; transition: none; } .ts-panel, .ts-card, .ts-story, .ts-filter { transition: none; }
}
