/* Moved verbatim from templates/therapy/landing.html (inline <style>) so it can be
   cached. Keep in sync with that template; cascade position = the
   <link> that replaced the <style> block. */
:root{
  /* Brand kit v2: Therapy Teal primary, Session Rust as rare accent.
     Mirrors src/fieldvio/static/css/therapy-redesign.css so this page
     stays in sync if therapy-redesign.css is bypassed by a future
     refactor. */
  --ts-paper:#ECE6D8;--ts-paper-hi:#F0EADC;--ts-paper-2:#E3DCC9;--ts-paper-deep:#D4CCB6;--ts-cream:#F0E8D5;
  --ts-ink:#14110E;--ts-ink-2:#221D18;--ts-ink-soft:#6B6258;--ts-ink-mute:#6B6258;
  --ts-noir:#0D0B09;--ts-noir-2:#1A1612;
  --ts-teal:#1F8C8C;--ts-teal-300:#6FAFAE;--ts-teal-500:#1F8C8C;--ts-teal-600:#1B7F7F;
  --ts-teal-700:#0F5F62;--ts-teal-deep:#0F5F62;--ts-teal-mute:#6FAFAE;
  --ts-rust:#C8693A;--ts-rust-300:#D78E63;--ts-rust-500:#C8693A;--ts-rust-700:#9A4A23;
  --ts-rust-deep:#9A4A23;--ts-rust-glow:#D78E63;
  --ts-mustard:#D4A24A;
  --slab:'Sora','Helvetica Neue',Helvetica,Arial,sans-serif;
  --display:'Sora',sans-serif;
  --serif:'Sora','Helvetica Neue',Helvetica,Arial,sans-serif;
  --body:'Hanken Grotesk','Helvetica Neue',Helvetica,Arial,sans-serif;
  --mono:'Hanken Grotesk','Helvetica Neue',Helvetica,Arial,sans-serif;
  --hand:'Caveat','Bradley Hand',cursive;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;}
body{background:var(--ts-paper);color:var(--ts-ink);font-family:var(--body);font-weight:400;line-height:1.6;overflow-x:clip;position:relative;}
img{max-width:100%;display:block;}

/* FILM GRAIN */
body::before{content:'';position:fixed;top:-12%;left:-12%;right:-12%;bottom:-12%;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.92' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='320' height='320' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");background-size:280px 280px;opacity:0.2;mix-blend-mode:multiply;pointer-events:none;z-index:200;animation:ts-film-grain 0.85s steps(10) infinite;will-change:transform;}
@keyframes ts-film-grain{0%{transform:translate(0,0);}10%{transform:translate(-3%,-4%);}20%{transform:translate(2%,3%);}30%{transform:translate(-5%,2%);}40%{transform:translate(4%,-2%);}50%{transform:translate(-2%,4%);}60%{transform:translate(3%,-3%);}70%{transform:translate(-4%,-1%);}80%{transform:translate(2%,3%);}90%{transform:translate(-1%,2%);}100%{transform:translate(0,0);}}

/* VIGNETTE + fold crease */
body::after{content:'';position:fixed;inset:0;background:radial-gradient(ellipse 100% 90% at 50% 50%,transparent 45%,rgba(14,14,16,0.06) 80%,rgba(14,14,16,0.22) 100%),linear-gradient(90deg,transparent calc(50% - 1px),rgba(14,14,16,0.05) 50%,transparent calc(50% + 1px));pointer-events:none;z-index:201;mix-blend-mode:multiply;}

/* FILM OVERLAY — light leaks + flicker + dust */
.ts-film{position:fixed;inset:0;pointer-events:none;z-index:199;background:radial-gradient(ellipse 70% 50% at 18% 22%,rgba(31,140,140,0.07),transparent 60%),radial-gradient(ellipse 60% 70% at 88% 78%,rgba(90,150,150,0.06),transparent 60%),radial-gradient(ellipse 50% 40% at 78% 18%,rgba(212,162,74,0.05),transparent 65%);mix-blend-mode:screen;animation:ts-film-flicker 5s ease-in-out infinite;}
.ts-film::after{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 15% 33%,rgba(14,14,16,0.5) 1px,transparent 2px),radial-gradient(circle at 78% 11%,rgba(14,14,16,0.4) 0.8px,transparent 1.6px),radial-gradient(circle at 42% 88%,rgba(14,14,16,0.45) 1.1px,transparent 2.2px),radial-gradient(circle at 91% 64%,rgba(14,14,16,0.35) 0.9px,transparent 1.8px),radial-gradient(circle at 6% 71%,rgba(14,14,16,0.4) 1px,transparent 2px);opacity:0.3;animation:ts-film-dust 0.4s steps(4) infinite;mix-blend-mode:multiply;}
@keyframes ts-film-flicker{0%,100%{opacity:1;}3%{opacity:0.88;}4%{opacity:1;}18%{opacity:0.94;}44%{opacity:0.96;}60%{opacity:1;}73%{opacity:0.93;}88%{opacity:1;}}
@keyframes ts-film-dust{0%{transform:translate(0,0);opacity:0.3;}25%{transform:translate(2%,-1%);opacity:0.18;}50%{transform:translate(-1%,2%);opacity:0.32;}75%{transform:translate(1%,1%);opacity:0.22;}100%{transform:translate(0,0);opacity:0.3;}}
/* Perf: the film-grain/dust/flicker layers repaint the whole
   viewport ~10x/sec forever. Keep the static texture but stop the
   constant motion on phones and for reduced-motion users — this is
   the biggest mobile TBT/jank win. */
@media (max-width:768px),(prefers-reduced-motion:reduce){
  body::before{animation:none!important;will-change:auto!important;}
  .ts-film{animation:none!important;}
  .ts-film::after{animation:none!important;}
  /* Don't gate content paint on scroll-reveal JS — otherwise the
     largest element can stay opacity:0 and Lighthouse reports
     NO_LCP. Show everything immediately; kills the entrance
     animation on phones only (desktop keeps it). */
  .r,.r.r-l,.r.r-r,.r.r-zoom,.r.r-tilt,.r-stagger > *,.ts-hero-h .l{
    opacity:1!important;transform:none!important;
    transition:none!important;will-change:auto!important;
  }
  /* LCP: big headings use background-clip:text + transparent fill,
     which Chrome does NOT count as an LCP-eligible element — that's
     why mobile reports NO_LCP. Render them as solid brand colour on
     phones so there's always a large contentful paint. Desktop keeps
     the gradient/grain effect. */
  .ts-flyer-title .l1,.ts-up-flyer-title .l1,.ts-edt-thurs,.ts-foot-h{
    background-image:none!important;-webkit-text-fill-color:#F0EADC!important;
    color:#F0EADC!important;text-shadow:none!important;filter:none!important;
  }
  .ts-flyer-title .l2,.ts-up-flyer-title .l2,.ts-edt-thurs em,.ts-foot-h em{
    background-image:none!important;-webkit-text-fill-color:#6FAFAE!important;
    color:#6FAFAE!important;text-shadow:none!important;filter:none!important;
  }
}

/* HEADER */
.ts-head{position:sticky;top:0;z-index:100;padding:18px 32px;background:var(--ts-noir, #0D0B09);backdrop-filter:blur(7px) saturate(1.5);-webkit-backdrop-filter:blur(7px) saturate(1.5);border-bottom:0;display:flex;align-items:center;justify-content:space-between;gap:24px;color:var(--ts-paper-hi);}
.ts-head-mark{display:flex;align-items:center;gap:14px;text-decoration:none;color:var(--ts-paper-hi);}
.ts-head-badge{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;border:1px solid rgba(14,14,16,0.18);box-shadow:0 2px 6px rgba(14,14,16,0.15);}
.ts-head-badge img{width:100%;height:100%;object-fit:cover;display:block;}
.ts-head-name{font-family:var(--slab);font-weight:800;font-size:1.05rem;letter-spacing:0.04em;text-transform:uppercase;line-height:1;}
.ts-head-tagline{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.18em;text-transform:uppercase;color:rgba(244,236,218,0.7);margin-top:4px;}
.ts-head-nav{display:flex;align-items:center;gap:28px;}
.ts-head-nav a{font-family:var(--mono);font-size:0.7rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-soft);text-decoration:none;transition:color 0.15s;}
.ts-head-nav a:hover{color:var(--ts-teal);}
.ts-head-cta{font-family:var(--mono);font-weight:500;font-size:0.66rem;letter-spacing:0.2em;text-transform:uppercase;background:var(--ts-ink);color:#fff;padding:11px 18px;text-decoration:none;border:1px solid var(--ts-ink);transition:all 0.15s;}
.ts-head-cta:hover{background:var(--ts-teal);border-color:var(--ts-teal);}
/* Menu button — replaces the cta in the header. Square icon-only
   button matching the public portal pattern; flips between bi-list
   (open) and bi-x-lg (close) when #brandMenu is open. */
.ts-head-menu{width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;background:var(--ts-ink);color:#fff;border:1px solid var(--ts-ink);cursor:pointer;font-size:1.2rem;line-height:1;transition:background 0.15s,border-color 0.15s,color 0.15s;flex:0 0 auto;}
.ts-head-menu:hover{background:var(--ts-teal);border-color:var(--ts-teal);}
.ts-head-menu .menu-icon-close{display:none;}
.ts-head-menu[aria-expanded="true"] .menu-icon-open{display:none;}
.ts-head-menu[aria-expanded="true"] .menu-icon-close{display:inline-block;}

/* TICKER */
.ts-ticker{background:var(--ts-noir, #0D0B09);color:var(--ts-paper-hi, #F0EADC);padding:10px 0;overflow:hidden;position:relative;border-bottom:0;}
.ts-ticker::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.06) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
/* Infinite marquee — content is duplicated in markup so the loop is
   seamless. Animation slides the track left by exactly 50% (one full
   copy width) and restarts. Hover pauses the scroll. */
.ts-ticker-track{display:flex;align-items:center;gap:36px;font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;white-space:nowrap;width:max-content;animation:ts-tick 32s linear infinite;will-change:transform;}
.ts-ticker:hover .ts-ticker-track{animation-play-state:paused;}
.ts-ticker-track span{display:inline-flex;align-items:center;gap:14px;color:rgba(244,236,218,0.78);flex:0 0 auto;padding-right:36px;position:relative;}
.ts-ticker-track span::after{content:'◉';color:var(--ts-teal-300, #6FAFAE);font-size:0.7em;position:absolute;right:0;top:50%;transform:translateY(-50%);}
@keyframes ts-tick{from{transform:translateX(0);}to{transform:translateX(-50%);}}
.ts-ticker.ts-ticker--static{position:relative;}
@media(max-width:780px){
  .ts-ticker-track{gap:22px;font-size:0.58rem;letter-spacing:0.16em;}
  .ts-ticker-track span{padding-right:22px;}
}

/* Brand band styles removed — moved into the cream sticky header
   via _partials/therapy_head_cream.html. */

/* HERO — dark band. Flyer + headline restored; only the surface
   colour flipped to noir so it bookends the dark header + ticker
   without a cream gap. Text + eyebrow + italic accents re-tinted
   for dark readability. */
.ts-hero{
  padding:64px 32px 26px;position:relative;
  background:var(--ts-noir, #0D0B09);color:var(--ts-paper-hi, #F0EADC);
  border-bottom:0;
}
.ts-hero > .ts-hero-grid,.ts-hero > .ts-mine{
  max-width:1340px;margin-left:auto;margin-right:auto;
}
.ts-hero .ts-mine{
  background:rgba(244,236,218,0.04);color:var(--ts-paper-hi);
  border:1px solid rgba(244,236,218,0.16);
}
.ts-hero .ts-mine .ts-mine-tag{color:var(--ts-teal-300, #6FAFAE);}
.ts-hero .ts-mine .ts-mine-h{color:var(--ts-paper-hi);}
.ts-hero .ts-mine .ts-mine-h em{color:var(--ts-teal-300);}
.ts-hero .ts-mine .ts-mine-meta,.ts-hero .ts-mine .ts-mine-fineprint{color:rgba(244,236,218,0.7);}
.ts-hero-meta{display:flex;justify-content:space-between;align-items:baseline;font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);padding-bottom:14px;border-bottom:1px solid rgba(14,14,16,0.14);margin-bottom:64px;flex-wrap:wrap;gap:14px;}
.ts-hero-grid{display:grid;grid-template-columns:0.75fr 1fr;gap:64px;align-items:center;}
/* Flyer ~50% smaller per spec — cap so it doesn't crowd the hero copy. */
.ts-flyer-wrap{position:relative;perspective:1200px;z-index:2;max-width:340px;}
.ts-flyer{background:var(--ts-ink);color:#fff;padding:26px 26px 22px;position:relative;transform:rotate(-1.4deg);box-shadow:0 32px 60px -22px rgba(14,14,16,0.5),0 6px 16px rgba(14,14,16,0.18),inset 0 0 60px rgba(0,0,0,0.4);overflow:hidden;aspect-ratio:1.7/1;display:flex;flex-direction:column;}
/* When the hero card is the static Cloudflare flyer image, drop the
   CSS-art chrome (padding, halftone, vignette) so the image fills.
   `aspect-ratio:auto` + `height:auto` + `object-fit:contain` together
   ensure the natural aspect of the poster is honored — no top/bottom
   crop when a portrait image is used. */
/* Hero flyer image: cropped short (down to ~the chandelier) instead
   of the full tall poster. Fixed landscape ratio + cover from the top. */
.ts-flyer.ts-flyer--img{padding:0;background:transparent;box-shadow:0 32px 60px -22px rgba(14,14,16,0.5),0 6px 16px rgba(14,14,16,0.18);text-decoration:none;display:block;aspect-ratio:auto;overflow:hidden;}
.ts-flyer.ts-flyer--img::before,.ts-flyer.ts-flyer--img::after{display:none;}
.ts-flyer.ts-flyer--img img{display:block;width:100%;height:auto;max-height:none;object-fit:contain;}
/* Handwritten caption on the polaroid's bottom strip — same Playfair
   italic the Hello Goodbye stamp uses elsewhere on the flyer, so it
   reads as a marker scribble on the white border of a picture card. */
.ts-flyer-caption{
  position:absolute;left:0;right:0;bottom:4.5%;
  font-family:var(--serif);font-style:italic;font-weight:500;
  font-size:clamp(0.78rem,1.4vw,0.95rem);
  letter-spacing:0.04em;color:var(--ts-ink);
  text-align:center;transform:rotate(-1.2deg);
  text-shadow:0 0.5px 0 rgba(14,14,16,0.06);
  pointer-events:none;z-index:3;
}
.ts-flyer::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.07) 0.5px,transparent 1px);background-size:3.5px 3.5px;pointer-events:none;}
.ts-flyer::after{content:'';position:absolute;top:0;bottom:0;left:50%;width:1px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,0.07) 30%,rgba(255,255,255,0.1) 50%,rgba(255,255,255,0.07) 70%,transparent);pointer-events:none;}
.ts-flyer-corner{position:absolute;top:22px;right:22px;width:64px;height:64px;border-radius:50%;overflow:hidden;z-index:2;display:flex;align-items:center;justify-content:center;}
.ts-flyer-corner img{width:100%;height:100%;object-fit:cover;display:block;}
.ts-flyer-arrow{position:absolute;left:30px;top:54%;width:0;height:0;border-top:9px solid transparent;border-bottom:9px solid transparent;border-left:14px solid var(--ts-teal);z-index:2;}

.ts-flyer-title{position:relative;z-index:1;line-height:0.84;letter-spacing:-0.015em;}
.ts-flyer-title .l1,.ts-flyer-title .l2{font-family:var(--slab);font-weight:900;font-size:clamp(3rem,7vw,5.8rem);text-transform:uppercase;display:block;}
.ts-flyer-title .l1{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.36'/%3E%3C/svg%3E"),linear-gradient(178deg,#A6CACA 0%,#82B0B0 55%,#5C8585 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:2px 1.5px 0 rgba(31,140,140,0.32),-1.5px 0 0 rgba(255,255,255,0.05),0 0 8px rgba(90,150,150,0.18);filter:contrast(0.96);}
.ts-flyer-title .l2{margin-top:-8px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E"),linear-gradient(178deg,#6FAFAE 0%,#1F8C8C 55%,#0F5F62 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:2px 1.5px 0 rgba(90,150,150,0.28),-1.5px 0 0 rgba(255,255,255,0.05),0 0 8px rgba(31,140,140,0.18);filter:contrast(0.95);}
.ts-flyer-sub{font-family:var(--slab);font-weight:700;font-size:0.85rem;letter-spacing:0.2em;text-transform:uppercase;color:#fff;margin-top:14px;padding:7px 12px;background:rgba(245,238,221,0.05);border:1px solid rgba(245,238,221,0.16);align-self:flex-start;}

/* Vertical-bar equalizer with halftone-dot print texture (each bar is
   a teal/cream/rust column that pulses on scroll — see the beat
   keyframes below). */
/* Bars live inside .ts-flyer-foot now, sandwiched between Every Thursday
   and Hello Goodbye. Heights are smaller to fit the foot row, and the
   beat is driven directly by scrollY (see paintBars() in the JS block).
   No CSS animation — bar positions are deterministic from scroll position
   so they stay put when scroll stops, and reverse on scroll-up. */
.ts-bars{display:flex;flex-direction:row;align-items:flex-end;gap:7px;position:relative;z-index:1;flex:1 1 auto;height:78px;justify-content:center;align-self:flex-end;}
.ts-bar{width:14px;flex:0 0 auto;background-color:var(--ts-cream);transform-origin:bottom center;will-change:transform;
  background-image:radial-gradient(circle,rgba(14,14,16,0.40) 0.55px,transparent 1.1px);
  background-size:2.8px 2.8px;background-position:center;}
.ts-bar.t{background-color:var(--ts-teal);width:16px;height:58px;}
/* Orange bars stay rust regardless of the per-venue accent override —
   the equaliser is meant to read teal+orange on every accent so the
   brand signature carries even on plum / forest / ocean accents. */
.ts-bar.r{background-color:#C8693A;width:18px;height:74px;}
.ts-bar.c{background-color:var(--ts-cream);width:14px;height:34px;}
.ts-bar.t2{background-color:var(--ts-teal-deep);width:16px;height:46px;}
.ts-bar.r2{background-color:#9A4A23;width:14px;height:26px;}
.ts-bar.c2{background-color:var(--ts-cream);width:14px;height:42px;opacity:0.85;}

.ts-flyer-foot{margin-top:auto;padding-top:14px;display:flex;justify-content:space-between;align-items:flex-end;gap:14px;position:relative;z-index:1;}
.ts-flyer-thurs{font-family:var(--slab);font-weight:900;font-size:1.35rem;letter-spacing:-0.01em;line-height:0.88;text-transform:uppercase;color:var(--ts-cream);flex:0 0 auto;}
.ts-flyer-thurs span{display:block;font-family:var(--mono);font-weight:400;font-size:0.55rem;letter-spacing:0.22em;color:var(--ts-teal-mute);margin-top:6px;}
.ts-flyer-hg{font-family:var(--serif);font-style:italic;font-size:0.95rem;color:var(--ts-cream);transform:rotate(-3deg);text-align:right;line-height:1.05;flex:0 0 auto;}
.ts-flyer-hg em{display:block;font-size:1.18em;margin-top:-3px;padding-left:14px;}

.ts-hero-copy{padding-left:8px;}
.ts-hero-eyebrow{font-family:var(--mono);font-size:0.7rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-paper-hi, #F0EADC);margin-bottom:24px;display:flex;align-items:center;gap:10px;}
.ts-hero-eyebrow::before{content:'';width:22px;height:1.5px;background:var(--ts-paper-hi, #F0EADC);}
.ts-hero-eyebrow h1{margin:0;display:inline;font-family:inherit;font-size:inherit;font-weight:inherit;letter-spacing:inherit;text-transform:inherit;line-height:inherit;color:inherit;}
.ts-hero-h{font-family:var(--slab);font-weight:800;font-size:clamp(2.6rem,4.6vw,4.4rem);line-height:0.95;letter-spacing:-0.02em;color:var(--ts-paper-hi, #F0EADC);margin-bottom:12px;overflow:hidden;padding-bottom:0.18em;}
.ts-hero-h .l{display:block;opacity:0;transform:translateY(60%);transition:opacity 0.7s cubic-bezier(0.2,0.6,0.2,1),transform 0.7s cubic-bezier(0.2,0.6,0.2,1);padding-bottom:0.06em;}
.ts-hero-h.is-in .l{opacity:1;transform:translateY(0);}
.ts-hero-h.is-in .l:nth-child(2){transition-delay:0.18s;}
.ts-hero-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal-300, #6FAFAE);letter-spacing:-0.005em;}
.ts-hero-h em::after{content:'.';color:var(--ts-teal-300, #6FAFAE);}
.ts-hero-desc{font-size:1rem;line-height:1.78;color:rgba(244,236,218,0.78);max-width:480px;margin-bottom:18px;}
.ts-hero-link{color:var(--ts-teal-300,#6FAFAE);text-decoration:none;font-weight:600;transition:color .15s;}
.ts-hero-link:hover{color:#fff;}
.ts-hero-actions{display:flex;gap:12px;flex-wrap:wrap;}
.ts-btn-p{background:var(--ts-teal);color:#fff;font-family:var(--mono);font-size:0.72rem;font-weight:500;letter-spacing:0.2em;text-transform:uppercase;padding:14px 26px;text-decoration:none;border:1px solid var(--ts-teal);transition:all 0.15s;cursor:pointer;display:inline-block;}
.ts-btn-p:hover{background:var(--ts-teal-700);border-color:var(--ts-teal-700);transform:translateY(-1px);}
/* Rust variant — Next event pill on the hero. Per direction "too much
   teal here", swap to the rust orange accent so the CTA contrasts the
   teal RSVP pill in the header instead of repeating it. */
/* Fill is #B25631, not var(--ts-rust) (#C8693A): white on the token is
   3.79:1 and fails AA, #B25631 is 4.92:1. Only the button FILL moves — the
   --ts-rust token keeps its value because it also drives decorative
   shadows/borders elsewhere, and darkening it globally would shift those. */
.ts-btn-p--rust{background:#B25631!important;border-color:#B25631!important;box-shadow:0 4px 0 var(--ts-rust-deep,#9A4A23),0 14px 28px -10px rgba(200,105,58,0.55)!important;}
.ts-btn-p--rust:hover{background:var(--ts-rust-deep,#9A4A23)!important;border-color:var(--ts-rust-deep,#9A4A23)!important;}
.ts-btn-s{background:transparent;color:var(--ts-ink);font-family:var(--mono);font-size:0.72rem;font-weight:500;letter-spacing:0.2em;text-transform:uppercase;padding:14px 26px;text-decoration:none;border:1px solid var(--ts-ink);transition:all 0.15s;cursor:pointer;display:inline-block;}
.ts-btn-s:hover{background:var(--ts-ink);color:#fff;}

.ts-hero-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:28px;margin-top:56px;padding-top:28px;border-top:1px solid rgba(14,14,16,0.14);}
.ts-stat-num{font-family:var(--slab);font-weight:900;font-size:2.4rem;line-height:1;color:var(--ts-teal-deep);margin-bottom:6px;letter-spacing:-0.01em;}
.ts-stat-label{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);}

/* SECTION */
section.s{max-width:1340px;margin:0 auto;padding:90px 32px;position:relative;}
.s-head{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:24px;margin-bottom:48px;}
.s-tag{font-family:var(--mono);font-size:0.7rem;letter-spacing:0.24em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:14px;display:flex;align-items:center;gap:12px;}
.s-tag::before{content:'';width:22px;height:1px;background:var(--ts-teal);}
.s-h{font-family:var(--slab);font-weight:800;font-size:clamp(2.2rem,4vw,3.6rem);line-height:0.98;letter-spacing:-0.02em;color:var(--ts-ink);max-width:740px;}
.s-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal-deep);}
.s-desc{font-size:0.98rem;line-height:1.78;color:var(--ts-ink-soft);max-width:520px;margin-top:14px;}

/* WWD */
.ts-wwd{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;}
.ts-wwd-card{background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:34px 30px;position:relative;}
.ts-wwd-card::before{content:'';position:absolute;top:0;left:0;width:60px;height:3px;background:var(--ts-teal);}
.ts-wwd-card.alt::before{background:var(--ts-teal-deep);}
.ts-wwd-no{font-family:var(--mono);font-size:0.62rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);margin-bottom:8px;}
.ts-wwd-num{font-family:var(--slab);font-weight:900;font-size:2.6rem;line-height:1;color:var(--ts-teal);margin-bottom:18px;letter-spacing:-0.01em;}
.ts-wwd-card.alt .ts-wwd-num{color:var(--ts-teal-deep);}
.ts-wwd-name{font-family:var(--slab);font-weight:800;font-size:1.35rem;letter-spacing:0.02em;text-transform:uppercase;color:var(--ts-ink);margin-bottom:12px;line-height:1.05;}
.ts-wwd-body{font-size:0.92rem;line-height:1.72;color:var(--ts-ink-soft);}

/* NEXT-SESSION 3-CARD STACK — secondary | main | tall */
.ts-next-stack{display:grid;grid-template-columns:0.7fr 1.4fr 0.7fr;gap:22px;align-items:stretch;}
.ts-next-card{position:relative;cursor:pointer;transition:transform 0.55s cubic-bezier(0.5,0.1,0.2,1),box-shadow 0.4s,opacity 0.4s;background:var(--ts-ink);overflow:hidden;border:1px solid rgba(14,14,16,0.16);}
.ts-next-card::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.07) 0.5px,transparent 1px);background-size:3px 3px;pointer-events:none;z-index:1;}
.ts-next-card.is-main{aspect-ratio:5/4;transform:rotate(-1deg);box-shadow:0 32px 60px -22px rgba(14,14,16,0.5),0 6px 16px rgba(14,14,16,0.2);}
.ts-next-card.is-side{aspect-ratio:3/5;transform:rotate(2deg);opacity:0.92;}
.ts-next-card.is-tall{aspect-ratio:3/5;transform:rotate(-2.4deg);opacity:0.92;}
.ts-next-card:hover{opacity:1;transform:rotate(0) translateY(-4px);box-shadow:0 20px 40px -18px rgba(14,14,16,0.4);}
.ts-next-card img{width:100%;height:100%;object-fit:cover;position:relative;z-index:0;}
.ts-next-card .ts-card-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;text-align:center;color:rgba(245,238,221,0.5);font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;line-height:1.7;height:100%;position:relative;z-index:2;}
.ts-card-overlay{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:18px;color:#fff;background:linear-gradient(to top,rgba(14,14,16,0.85) 0%,rgba(14,14,16,0.4) 50%,transparent 100%);z-index:2;}
.ts-card-overlay-tag{font-family:var(--mono);font-size:0.58rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal-mute);margin-bottom:6px;}
.ts-card-overlay-title{font-family:var(--slab);font-weight:800;font-size:1.05rem;line-height:1;letter-spacing:0.02em;text-transform:uppercase;color:#fff;}
.ts-card-rsvp{margin-top:10px;align-self:flex-start;font-family:var(--mono);font-weight:600;font-size:0.6rem;letter-spacing:0.18em;text-transform:uppercase;background:var(--ts-teal);color:#fff;border:1px solid var(--ts-teal);padding:8px 12px;cursor:pointer;transition:background 0.15s,transform 0.15s;}
.ts-card-rsvp:hover{background:var(--ts-teal-700);border-color:var(--ts-teal-700);transform:translateY(-1px);}
.ts-card-rsvp--main{font-size:0.66rem;padding:10px 16px;}
.ts-next-meta{margin-top:36px;padding-top:24px;border-top:1px solid rgba(14,14,16,0.14);display:grid;grid-template-columns:1fr auto;gap:24px;align-items:end;}
.ts-next-no{font-family:var(--mono);font-size:0.7rem;letter-spacing:0.24em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:14px;display:flex;align-items:center;gap:12px;}
.ts-next-no::before{content:'';width:24px;height:1px;background:var(--ts-teal);}
.ts-next-title{font-family:var(--slab);font-weight:800;font-size:clamp(1.8rem,3.2vw,2.8rem);line-height:0.96;letter-spacing:-0.02em;color:var(--ts-ink);margin-bottom:10px;}
.ts-next-title em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
.ts-next-date{font-family:var(--slab);font-weight:800;font-size:1.4rem;letter-spacing:0.02em;text-transform:uppercase;color:var(--ts-teal-deep);}
.ts-next-venue{font-family:var(--mono);font-size:0.72rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-soft);margin-top:6px;}
.ts-next-actions{display:flex;gap:12px;flex-wrap:wrap;}

/* ROSTER */
.ts-roster-actions{display:flex;gap:10px;flex-wrap:wrap;}
.ts-roster-wrap{position:relative;}
.ts-roster-clip{overflow:hidden;}
.ts-roster{display:flex;transition:transform 0.65s cubic-bezier(0.5,0.05,0.2,1);will-change:transform;}
.ts-roster-page{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;flex:0 0 100%;width:100%;}
.ts-roster[data-page="1"]{transform:translateX(-100%);}
.ts-dj{background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:24px 20px;transition:transform 0.2s,border-color 0.2s,box-shadow 0.2s;text-decoration:none;color:var(--ts-ink);display:flex;flex-direction:column;}
.ts-dj:hover{border-color:var(--ts-teal);transform:translateY(-2px);box-shadow:0 14px 28px -16px rgba(14,14,16,0.22);}
.ts-dj-av{width:54px;height:54px;border-radius:50%;background:radial-gradient(circle at 30% 30%,var(--ts-teal-mute),var(--ts-ink) 75%);display:flex;align-items:center;justify-content:center;font-family:var(--slab);font-weight:900;font-size:1.2rem;color:#fff;margin-bottom:18px;letter-spacing:-0.04em;background-size:cover;background-position:center;overflow:hidden;}
.ts-dj.r .ts-dj-av{background:radial-gradient(circle at 30% 30%,var(--ts-teal-300),var(--ts-ink) 75%);}
.ts-dj-av img{width:100%;height:100%;object-fit:cover;}
.ts-dj-name{font-family:var(--slab);font-weight:800;font-size:1.15rem;letter-spacing:0.02em;text-transform:uppercase;line-height:1.1;margin-bottom:4px;}
.ts-dj-genre{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:12px;}
.ts-dj-bio{font-size:0.82rem;line-height:1.7;color:var(--ts-ink-soft);}
.ts-roster-nav{display:flex;justify-content:space-between;align-items:center;margin-top:34px;padding-top:24px;border-top:1px solid rgba(14,14,16,0.14);flex-wrap:wrap;gap:18px;}
.ts-roster-counter{font-family:var(--mono);font-size:0.68rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);}
.ts-roster-counter span{color:var(--ts-teal);font-weight:500;}
.ts-roster-arrows{display:flex;gap:8px;}
.ts-roster-arrow{width:44px;height:44px;border:1px solid var(--ts-ink);background:transparent;color:var(--ts-ink);cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;transition:all 0.15s;font-family:var(--body);}
.ts-roster-arrow:hover{background:var(--ts-teal);color:#fff;border-color:var(--ts-teal);}

/* UPCOMING SESSIONS — dark band, italic display heading on left + stacked
   event flyer cards on right (mirrors the reference "Skills that turn
   briefs..." layout). Cards are clickable → ts-event-chooser modal. */
/* Constrain the dark band so it doesn't stretch edge-to-edge on
   desktop/tablet. Side gutter stays at 24px until the section hits its
   max-width (~1240px), then auto-margins centre it. */
.ts-upcoming{background:var(--ts-ink);color:#fff;padding:80px 32px;position:relative;overflow:visible;margin:32px 0;max-width:none;width:100%;border-radius:0;}
@media(max-width:780px){.ts-upcoming{margin:18px 0;width:100%;border-radius:0;padding:40px 22px 48px;}}
.ts-upcoming::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.04) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
.ts-upcoming-inner{max-width:1340px;margin:0 auto;position:relative;z-index:1;}
.ts-upcoming-left{padding:0;max-width:680px;margin:0 0 40px;}
.ts-upcoming-eyebrow{font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:24px;display:flex;align-items:center;gap:12px;}
.ts-upcoming-eyebrow::before{content:'';width:36px;height:1px;background:var(--ts-teal);}
.ts-upcoming-h{font-family:var(--slab);font-weight:400;font-size:clamp(2.6rem,5.2vw,4.6rem);line-height:0.96;letter-spacing:-0.02em;color:var(--ts-paper-hi,#F0EADC);margin-bottom:28px;}
.ts-upcoming-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal-300);}
.ts-upcoming-h em::after{content:'.';color:var(--ts-teal-300);}
.ts-upcoming-lede{max-width:440px;color:rgba(245,238,221,0.7);font-size:0.95rem;line-height:1.85;margin-bottom:32px;}
.ts-upcoming-link{display:inline-flex;align-items:center;font-family:var(--mono);font-size:0.7rem;letter-spacing:0.2em;text-transform:uppercase;color:#fff;text-decoration:none;padding-bottom:6px;border-bottom:1px solid var(--ts-teal);transition:gap 0.2s;}
.ts-upcoming-link:hover{color:var(--ts-teal-300);}
/* View full schedule CTA — primary rust button so the path from
   "next session" → /schedule is the loudest exit from this section. */
.ts-upcoming-cta{
  display:inline-flex; align-items:center; gap:10px;
  padding:13px 22px; border-radius:999px;
  background:var(--ts-teal); color:#fff;
  border:1px solid var(--ts-teal);
  text-decoration:none;
  font-family:var(--mono); font-size:0.7rem; font-weight:500;
  letter-spacing:0.2em; text-transform:uppercase;
  transition:background 0.15s, border-color 0.15s, transform 0.1s, box-shadow 0.15s;
  box-shadow:0 14px 28px -16px rgba(31,140,140,0.7);
}
.ts-upcoming-cta i{font-size:1rem;}
.ts-upcoming-cta:hover{background:var(--ts-teal-700, #0F5F62); border-color:var(--ts-teal-700, #0F5F62); transform:translateY(-1px); box-shadow:0 18px 34px -16px rgba(31,140,140,0.85);}
.ts-upcoming-cta:active{transform:scale(0.98);}
/* Full-schedule button — cream (not teal) so it reads as the calm
   secondary exit on the dark band. */
.ts-upcoming-schedbtn{display:inline-flex;align-items:center;gap:10px;padding:13px 24px;border-radius:999px;background:var(--ts-paper-hi,#F0EADC);color:var(--ts-ink,#0D0B09);border:1px solid var(--ts-paper-hi,#F0EADC);text-decoration:none;font-family:var(--mono);font-size:0.7rem;font-weight:500;letter-spacing:0.2em;text-transform:uppercase;transition:background 0.15s,transform 0.1s,box-shadow 0.15s;box-shadow:0 14px 28px -16px rgba(0,0,0,0.55);}
.ts-upcoming-schedbtn:hover{background:#fff;transform:translateY(-1px);box-shadow:0 18px 34px -16px rgba(0,0,0,0.6);}
.ts-upcoming-schedbtn:active{transform:scale(0.98);}
/* Row that hosts the Full-schedule button under the flyer stack. */
.ts-upcoming-schedbtn-row{margin-top:32px;display:flex;justify-content:flex-start;}
@media(max-width:780px){.ts-upcoming-schedbtn-row{margin-top:24px;}}
.ts-upcoming-counter{font-family:var(--mono);font-size:0.68rem;letter-spacing:0.22em;color:var(--ts-ink-mute);margin-top:36px;}
.ts-upcoming-stack{position:relative;display:flex;flex-direction:column;gap:26px;width:100%;}

/* ── Cream "This weekend" card grid (ported from /schedule) ───────
   Replaces the legacy featured-polaroid + line-up rail. A cream panel
   sits on the dark .ts-upcoming surface (1 big featured flyer + a
   2-card stack) so the homepage weekend block matches the schedule
   page's card style. All rules scoped under .ts-upcoming so the
   generic .event / .poster class names can't leak elsewhere. */
/* No light card wrapper — the weekend grid sits directly on the dark
   .ts-upcoming surface so it doesn't add a second layer of side padding
   on top of the section's own gutter. */
.ts-upcoming .sched-weekend-light{
  position:relative;background:transparent;color:var(--ts-paper-hi,#F0EADC);
  margin:0;padding:0;border-radius:0;box-shadow:none;
}
.ts-upcoming .sched-weekend-light .sec-head{
  display:flex;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:20px;flex-wrap:wrap;
}
@media (min-width:1200px){.ts-upcoming .sched-weekend-light .sec-head{margin-bottom:28px;}}
.ts-upcoming .sched-weekend-light .sec-h{
  font-family:var(--slab);font-weight:400;font-size:clamp(1.7rem, 3.6vw, 2.8rem);
  line-height:.98;letter-spacing:-0.02em;color:var(--ts-paper-hi,#F0EADC);margin:0;
}
.ts-upcoming .sched-weekend-light .sec-h em{
  font-family:var(--serif);font-style:italic;font-weight:400;
  color:var(--ts-teal-300,#6FAFAE);letter-spacing:-0.005em;
}
.ts-upcoming .sched-weekend-light .sec-meta{
  font-family:var(--mono);font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:rgba(244,236,218,0.66);
}
.ts-upcoming .sched-weekend-empty{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;
  color:rgba(244,236,218,0.55);padding:48px 0;text-align:center;
}
.ts-upcoming .sched-weekend-grid{display:grid;grid-template-columns:2fr 1fr;gap:6px;align-items:stretch;}
@media (min-width:720px){.ts-upcoming .sched-weekend-grid{gap:10px;}}
@media (min-width:1200px){.ts-upcoming .sched-weekend-grid{gap:14px;}}
.ts-upcoming .sched-weekend-grid .event{
  position:relative;background:var(--ts-noir-2,#1A1612);color:var(--ts-paper-hi);
  border:1px solid rgba(244,236,218,0.07);
  border-radius:12px;overflow:hidden;display:flex;flex-direction:column;min-height:0;
  text-decoration:none;cursor:pointer;transition:transform .18s ease, box-shadow .18s ease;isolation:isolate;
}
.ts-upcoming .sched-weekend-grid .event:hover{transform:translateY(-2px);box-shadow:0 18px 40px -22px rgba(0,0,0,.55);}
.ts-upcoming .sched-weekend-grid .event:focus-visible{outline:2px solid var(--ts-teal-300);outline-offset:3px;}
.ts-upcoming .sched-weekend-grid .event.featured{display:grid;grid-template-rows:1fr auto;min-height:0;}
.ts-upcoming .sched-weekend-stack{display:grid;grid-template-rows:1fr 1fr;gap:10px;min-height:0;}
@media (min-width:720px){.ts-upcoming .sched-weekend-stack{gap:18px;}}
@media (min-width:1200px){.ts-upcoming .sched-weekend-stack{gap:24px;}}
.ts-upcoming .sched-weekend-grid .event-head{
  position:absolute;top:0;left:0;right:0;z-index:3;display:flex;justify-content:space-between;align-items:center;
  padding:10px 12px;color:rgba(244,236,218,.92);
  font-family:var(--mono);font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;
  background:linear-gradient(180deg, rgba(13,11,9,.7), rgba(13,11,9,0));
}
.ts-upcoming .sched-weekend-grid .event-head .eh-l{display:inline-flex;align-items:center;gap:8px;}
.ts-upcoming .sched-weekend-grid .event-head .dot{
  width:7px;height:7px;border-radius:50%;background:var(--ts-teal-300);box-shadow:0 0 0 3px rgba(111,175,174,.18);
}
.ts-upcoming .sched-weekend-grid .poster{
  position:relative;background-color:var(--ts-noir-2);background-position:center;background-size:cover;
  background-repeat:no-repeat;aspect-ratio:4 / 5;min-height:0;container-type:inline-size;
}
.ts-upcoming .sched-weekend-grid .event.featured .poster{aspect-ratio:4 / 5;background-size:cover;background-position:center;min-height:0;}
.ts-upcoming .sched-weekend-grid .poster-halftone{
  position:absolute;inset:0;pointer-events:none;mix-blend-mode:multiply;opacity:.18;
  background-image:radial-gradient(rgba(0,0,0,.85) 1px, transparent 1.4px);background-size:5px 5px;
}
.ts-upcoming .sched-weekend-grid .poster-grain{
  position:absolute;inset:0;pointer-events:none;opacity:.32;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.7'/%3E%3C/svg%3E");
}
.ts-upcoming .sched-weekend-grid .event-foot .event-price{
  align-self:flex-start;display:inline-flex;align-items:center;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;font-weight:600;
  padding:5px 10px;border-radius:999px;background:var(--ts-teal-500, #1F8C8C);color:#fff;
  border:1px solid var(--ts-teal-500, #1F8C8C);margin-bottom:8px;
}
.ts-upcoming .sched-weekend-grid .event.featured .event-foot .event-price{font-size:.66rem;padding:6px 12px;}
.ts-upcoming .sched-weekend-grid .event-view{
  position:absolute;right:12px;bottom:12px;z-index:4;display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:50%;text-decoration:none;background:rgba(13,11,9,.78);color:var(--ts-paper-hi);
  border:1px solid rgba(244,236,218,.22);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:background .15s, color .15s, border-color .15s, transform .12s;
}
.ts-upcoming .sched-weekend-grid .event-view i{font-size:.95rem;line-height:1;}
.ts-upcoming .sched-weekend-grid .event-view:hover{background:var(--ts-teal-300);color:var(--ts-noir);border-color:var(--ts-teal-300);transform:translateY(-1px);}
.ts-upcoming .sched-weekend-grid .event.featured .event-view{width:38px;height:38px;}
.ts-upcoming .sched-weekend-grid .event.featured .event-view i{font-size:1.05rem;}
@media (max-width:560px){
  .ts-upcoming .sched-weekend-grid .event-view{width:30px;height:30px;}
  .ts-upcoming .sched-weekend-grid .event-view i{font-size:.82rem;}
  .ts-upcoming .sched-weekend-grid .event.featured .event-view{width:34px;height:34px;}
  .ts-upcoming .sched-weekend-grid .event.featured .event-view i{font-size:.92rem;}
}
.ts-upcoming .sched-weekend-grid .event-foot{
  position:relative;z-index:2;display:flex;flex-direction:column;gap:4px;padding:12px 14px 14px;
  background:linear-gradient(0deg, rgba(13,11,9,.92), rgba(13,11,9,.55) 70%, rgba(13,11,9,0));margin-top:-44px;
}
.ts-upcoming .sched-weekend-grid .event.featured .event-foot{margin-top:-60px;padding:18px 18px 18px;}
.ts-upcoming .sched-weekend-grid .event-foot .name{
  font-family:var(--slab);font-weight:400;font-size:.95rem;line-height:1.1;letter-spacing:-0.005em;color:var(--ts-paper-hi);
}
.ts-upcoming .sched-weekend-grid .event.featured .event-foot .name{font-size:clamp(1.1rem, 2.4vw, 1.7rem);}
.ts-upcoming .sched-weekend-grid .event-foot .meta{
  font-family:var(--mono);font-size:.58rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(244,236,218,.7);
}
.ts-upcoming .sched-weekend-grid .event.featured .event-foot .meta{font-size:.66rem;}
/* DJ line-up line inside the card foot — the names from screenshot 1
   (MARIST / BLACKSUN / JAY DI). */
.ts-upcoming .sched-weekend-grid .event-foot .lineup{
  font-family:var(--mono);font-size:.56rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ts-teal-300);line-height:1.5;margin-top:2px;
}
.ts-upcoming .sched-weekend-grid .event.featured .event-foot .lineup{font-size:.64rem;}

/* Event flyer cards in the stack — sized ~50% of the legacy flyer so
   the dark band reads as a tighter trio. Keeps main's 4:5 aspect-ratio
   art (see below) so the poster proportions stay intact at any width. */
.ts-up-card{position:relative;background:var(--ts-paper-hi);color:var(--ts-ink);width:100%;max-width:260px;border:1px solid rgba(14,14,16,0.12);overflow:hidden;cursor:pointer;transition:transform 0.4s cubic-bezier(0.5,0.1,0.2,1),box-shadow 0.4s;box-shadow:0 18px 36px -18px rgba(0,0,0,0.55),0 3px 8px rgba(0,0,0,0.22);display:flex;flex-direction:column;will-change:transform;border-radius:14px;}
.ts-up-card:hover{transform:translateY(-3px) rotate(0)!important;box-shadow:0 24px 44px -18px rgba(0,0,0,0.7),0 6px 14px rgba(0,0,0,0.3);}
.ts-up-card--featured{transform:rotate(-1.2deg);align-self:flex-start;margin-left:0;}
.ts-up-card__corner{display:flex;justify-content:space-between;align-items:center;padding:11px 14px 0;font-family:var(--mono);font-size:0.5rem;letter-spacing:0.22em;text-transform:uppercase;}
.ts-up-card__tag{color:var(--ts-teal);font-weight:600;}
.ts-up-card__num{color:var(--ts-ink-mute);}
/* Flyer art at canonical 1080x1350 (4:5 portrait), full-bleed inside
   the card. Card frame keeps its outer shadow + radius; the rounded
   poster fills the interior. Text sizes scale down to match the smaller
   card footprint. */
.ts-up-card__art{
  position:relative; background:var(--ts-ink);
  width:100%; aspect-ratio:1080/1350;
  margin:0; display:flex; align-items:stretch; justify-content:stretch;
  overflow:hidden; border-radius:0;
}
.ts-up-card__art--photo{
  display:block; width:100%; height:100%;
  margin:0; max-height:none;
  object-fit:cover; object-position:center;
}
.ts-up-card__foot{padding:0 14px 9px;}
.ts-up-card__name{font-family:var(--slab);font-weight:800;font-size:0.95rem;line-height:1.05;letter-spacing:-0.005em;color:var(--ts-ink);margin-bottom:4px;}
.ts-up-card__meta{font-family:var(--mono);font-size:0.54rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-mute);}
.ts-up-card__bottombar{display:flex;justify-content:space-between;padding:9px 14px;border-top:1px solid rgba(14,14,16,0.08);font-family:var(--mono);font-size:0.5rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);}

/* CSS-art mini-flyer used inside the featured card when there's no banner */
.ts-up-flyer{flex:1;display:flex;flex-direction:column;padding:24px 22px;color:#fff;position:relative;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.07) 0.5px,transparent 1px);background-size:3.5px 3.5px;}
.ts-up-flyer-corner{position:absolute;top:14px;right:14px;width:42px;height:42px;border-radius:50%;overflow:hidden;}
.ts-up-flyer-corner img{width:100%;height:100%;object-fit:cover;}
.ts-up-flyer-title{line-height:0.84;letter-spacing:-0.015em;}
.ts-up-flyer-title .l1,.ts-up-flyer-title .l2{font-family:var(--slab);font-weight:900;font-size:clamp(2.2rem,5vw,3.4rem);text-transform:uppercase;display:block;}
.ts-up-flyer-title .l1{background-image:linear-gradient(178deg,#A6CACA 0%,#82B0B0 55%,#5C8585 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;}
.ts-up-flyer-title .l2{margin-top:-6px;background-image:linear-gradient(178deg,#6FAFAE 0%,#1F8C8C 55%,#0F5F62 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;}
.ts-up-flyer-sub{font-family:var(--slab);font-weight:700;font-size:0.72rem;letter-spacing:0.2em;text-transform:uppercase;color:#fff;margin-top:10px;padding:5px 10px;background:rgba(245,238,221,0.06);border:1px solid rgba(245,238,221,0.18);align-self:flex-start;}


/* EXPLORE — 3-card band on cream paper, second section in the scroll. */
.ts-explore{background:var(--ts-paper, #ECE6D8);padding:84px 32px;position:relative;}
.ts-explore-inner{max-width:1340px;margin:0 auto;}
.ts-explore-head{margin-bottom:36px;}
.ts-explore-eyebrow{font-family:var(--mono);font-size:0.66rem;font-weight:600;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);margin:0 0 12px;display:flex;align-items:center;gap:12px;}
.ts-explore-eyebrow .sec-num{background:var(--ts-ink);color:var(--ts-paper);}
.ts-explore-h{font-family:var(--slab);font-weight:800;font-size:clamp(2.2rem,4.6vw,3.6rem);line-height:0.98;letter-spacing:-0.02em;color:var(--ts-ink);margin:0;}
.ts-explore-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
/* Horizontal scroller. No touch-action override on purpose: the
   default lets the browser disambiguate — a horizontal drag scrolls
   the cards, a vertical drag scrolls the PAGE (pan-x is what froze
   the season rail; we don't repeat that here). On desktop the three
   cards sum to 100% so there's no scroll; on phones each card is
   ~78% so the next one peeks and signals "there's more". */
.ts-explore-grid{display:flex;gap:18px;overflow-x:auto;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;-ms-overflow-style:none;
  scroll-padding-left:0;}
.ts-explore-grid::-webkit-scrollbar{display:none;}
.ts-explore-card{flex:0 0 clamp(260px,31%,360px);scroll-snap-align:start;
  display:flex;flex-direction:column;align-items:flex-start;text-align:left;background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:30px 28px 26px;position:relative;text-decoration:none;cursor:pointer;font:inherit;transition:transform 0.2s,border-color 0.2s,box-shadow 0.2s;}
.ts-explore-card::before{content:'';position:absolute;top:0;left:0;width:60px;height:3px;background:var(--ts-teal);}
.ts-explore-card.alt::before{background:var(--ts-teal-deep);}
.ts-explore-card:hover{transform:translateY(-3px);border-color:rgba(31,140,140,0.4);box-shadow:0 22px 40px -22px rgba(14,14,16,0.5);}
.ts-explore-tag{font-family:var(--mono);font-size:0.55rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-teal);font-weight:600;margin-bottom:14px;}
.ts-explore-card.alt .ts-explore-tag{color:var(--ts-teal-deep);}
.ts-explore-no{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);margin-bottom:14px;}
/* Board card — built but not shipped: greyed, still tappable so the
   click fires the shared coming-soon toast. */
.ts-explore-card--soon{opacity:0.62;cursor:not-allowed;}
.ts-explore-card--soon::before{background:var(--ts-ink-mute);}
.ts-explore-card--soon:hover{transform:none;border-color:rgba(14,14,16,0.1);box-shadow:none;}
.ts-explore-card--soon .ts-explore-tag,
.ts-explore-card--soon .ts-explore-go{color:var(--ts-ink-mute);}
.ts-explore-card--soon .ts-explore-ico{background:rgba(14,14,16,0.07);color:var(--ts-ink-mute);}
.ts-explore-ico{width:46px;height:46px;border-radius:50%;background:rgba(31,140,140,0.12);color:var(--ts-teal);display:flex;align-items:center;justify-content:center;font-size:1.2rem;margin-bottom:18px;}
.ts-explore-name{font-family:var(--slab);font-weight:800;font-size:1.3rem;letter-spacing:0.01em;text-transform:uppercase;color:var(--ts-ink);line-height:1.05;margin:0 0 10px;}
.ts-explore-body{font-size:0.92rem;line-height:1.7;color:var(--ts-ink-soft);margin-bottom:20px;}
.ts-explore-go{margin-top:auto;font-family:var(--mono);font-size:0.62rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-teal);font-weight:600;}
@media(max-width:780px){
  .ts-explore{padding:44px 16px;}
  .ts-explore-grid{gap:12px;}
  /* ~78% so the next card peeks ~22% — "there's more". */
  .ts-explore-card{flex:0 0 78%;padding:20px 16px 18px;}
  .ts-explore-ico{width:36px;height:36px;font-size:1rem;margin-bottom:12px;}
  .ts-explore-no{margin-bottom:10px;}
  .ts-explore-name{font-size:1rem;margin-bottom:7px;}
  .ts-explore-body{font-size:0.82rem;line-height:1.6;margin-bottom:14px;}
  .ts-explore-go{font-size:0.56rem;}
}

/* FEATURED row — true 75 / 25: flyer left, info panel right. Spans the
   full section width (the section is single-column now, not a nested
   half-width sub-grid, which is why the old 75/25 read as cramped). */
.ts-up-featured-row{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,1fr);gap:8px;align-items:stretch;width:100%;}
/* Flyer bleeds LEFT past the section edge but its right edge stays put
   (width grows by the bleed) so the gap to the side rail doesn't open
   up. Slight tilt for a fanciful poster-on-the-wall look. body has
   overflow-x:clip so no scrollbar. */
.ts-up-featured-row .ts-up-card--featured{--bleed:clamp(40px,9vw,96px);max-width:none;width:calc(100% + var(--bleed));margin:0 0 0 calc(-1 * var(--bleed));align-self:stretch;transform:rotate(-2.2deg);transform-origin:center left;}
.ts-up-featured-row .ts-up-card--featured:hover{transform:rotate(-2.2deg) translateY(-3px)!important;}
/* Canonical .polaroid-tpl v-white card on the homepage. Bleeds OUTSIDE
   the grid cell on the LEFT (same --bleed pattern the legacy
   ts-up-card--featured had) so the polaroid reads as "tossed onto
   the page" rather than "boxed by the layout". Tilted -2.2° to match. */
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid{
  --bleed:clamp(40px,9vw,96px);
  width:calc(100% + var(--bleed));max-width:none;
  margin:0 0 0 calc(-1 * var(--bleed));
  align-self:stretch;
  transform:rotate(-2.2deg);transform-origin:center left;
  cursor:pointer;transition:transform .35s cubic-bezier(.5,.1,.2,1),box-shadow .35s;
}
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid:hover,
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid:focus-visible{
  transform:rotate(-2.2deg) translateY(-3px);
}
@media (min-width:961px){
  /* Desktop: legacy ts-up-card used a tighter bleed here. */
  .ts-up-featured-row > .polaroid-tpl.ts-up-polaroid{--bleed:clamp(20px,3vw,52px);}
}
/* Caption: lock the right meta column so "Therapy" (title) doesn't
   collide with "MAY 28" (meta) when the polaroid is mobile-width. */
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid .pt-cap{gap:18px;}
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid .pt-meta{max-width:38%;}
.ts-up-featured-row > .polaroid-tpl.ts-up-polaroid:focus-visible{outline:2px solid var(--ts-rust);outline-offset:3px;}
.ts-up-polaroid-fallback{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;width:100%;background:linear-gradient(135deg,var(--ts-ink) 0%,var(--ts-teal-deep,#3F7C7C) 100%);color:var(--ts-paper);padding:24px;text-align:center;}
.ts-up-polaroid-fallback .ts-up-flyer-title{font-family:var(--slab,'Sora');font-size:38px;line-height:1.0;letter-spacing:-0.02em;}
.ts-up-polaroid-fallback .ts-up-flyer-title .l1{display:block;color:var(--ts-teal-300,#5FB6B8);}
.ts-up-polaroid-fallback .ts-up-flyer-title .l2{display:block;color:var(--ts-paper);}
.ts-up-polaroid-fallback .ts-up-flyer-sub{margin-top:12px;font-family:var(--mono,'Hanken Grotesk');font-size:11px;letter-spacing:0.18em;text-transform:uppercase;color:rgba(239,230,210,0.7);}
.ts-up-featured-row.is-locked > .polaroid-tpl.ts-up-polaroid .pt-photo .ph-img{filter:blur(14px) saturate(0.7) brightness(0.5);}
.ts-up-featured-row.is-locked > .polaroid-tpl.ts-up-polaroid .ts-up-lock{position:absolute;inset:auto 16px 16px 16px;z-index:3;}
/* Laptop/desktop: the 3:1 row + portrait 1080/1350 art made the flyer
   render ~1000px wide and taller than the viewport. Cap the stack
   width, ease the column ratio + left bleed, and constrain the art to
   a sane height so the featured poster fits on screen. Mobile keeps
   its already-tuned full-width treatment. */
@media(min-width:961px){
  .ts-upcoming-stack{max-width:1000px;margin-left:auto;margin-right:auto;}
  .ts-up-featured-row{grid-template-columns:minmax(0,2.1fr) minmax(0,1fr);}
  .ts-up-featured-row .ts-up-card--featured{--bleed:clamp(20px,3vw,52px);}
  .ts-up-featured-row .ts-up-card__art{aspect-ratio:auto;height:clamp(440px,54vh,580px);}
  .ts-up-featured-row .ts-up-card__art--photo{height:100%;object-fit:cover;}
}
/* Archivo Black ships a single weight (400). Requesting 800 made the
   browser synth-bold / drop the face on some mobiles — the "no font
   loaded" look. Use 400; the face is already black by design. */
.ts-up-card__name{font-weight:400;}
/* Column 2 wrapper: aligned to the top (not stretched to the flyer's
   height) so the venue/line-up box is only as tall as its contents.
   The RSVP button is a sibling below the box, not inside it. */
.ts-up-aside-wrap{display:flex;flex-direction:column;gap:14px;align-self:start;min-width:0;}
.ts-up-side{display:flex;flex-direction:column;gap:20px;min-width:0;background:rgba(245,238,221,0.04);border:1px solid rgba(245,238,221,0.1);border-radius:14px;padding:22px 20px;}
.ts-up-side-block{display:flex;flex-direction:column;gap:12px;}
.ts-up-side-label{font-family:var(--mono);font-size:0.56rem;letter-spacing:0.22em;text-transform:uppercase;color:rgba(245,238,221,0.5);}
/* Avatars only (no venue/DJ names) — bigger, centred in the rail. */
.ts-up-av{width:clamp(48px,5.5vw,64px);height:clamp(48px,5.5vw,64px);border-radius:50%;object-fit:cover;flex:0 0 auto;background:rgba(245,238,221,0.1);border:1px solid rgba(245,238,221,0.18);}
.ts-up-av--mark{display:flex;align-items:center;justify-content:center;overflow:hidden;}
.ts-up-av--mark img{width:100%;height:100%;object-fit:cover;}
.ts-up-av--ph{display:flex;align-items:center;justify-content:center;font-family:var(--slab);font-weight:400;font-size:1.3rem;color:var(--ts-teal-300);}
.ts-up-av--venue{display:flex;align-items:center;justify-content:center;color:var(--ts-teal-300);font-size:1.4rem;}
.ts-up-av--hglogo{display:block;background-color:#F2EBDF;-webkit-mask-image:url("https://imagedelivery.net/DMKHMoCI4OT1MdcrbL1WlA/87a3cd7e-9f3b-43ea-84be-a1bfe2bda300/headlogo");mask-image:url("https://imagedelivery.net/DMKHMoCI4OT1MdcrbL1WlA/87a3cd7e-9f3b-43ea-84be-a1bfe2bda300/headlogo");-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:78%;mask-size:78%;}
.ts-up-side-venue,.ts-up-dj{display:flex;align-items:center;justify-content:center;text-decoration:none;color:#fff;}
.ts-up-side-venue.is-static{cursor:default;pointer-events:none;}
.ts-up-dj{appearance:none;background:none;border:0;padding:0;margin:0;font:inherit;cursor:pointer;width:100%;}
.ts-up-dj .ts-up-av{transition:border-color .15s,transform .15s;}
.ts-up-dj:hover .ts-up-av,.ts-up-dj:focus-visible .ts-up-av{border-color:var(--ts-teal-300);transform:scale(1.05);}
.ts-up-dj:focus-visible{outline:2px solid var(--ts-teal-300);outline-offset:3px;border-radius:50%;}
.ts-up-side-djs{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;align-items:center;gap:14px;}
/* Full-width block in the narrow rail — was squished by the inline
   pill padding + 0.2em tracking in a ~80px column. */
.ts-up-side-rsvp{display:flex;width:100%;justify-content:center;padding:13px 12px;letter-spacing:0.12em;white-space:nowrap;gap:7px;}
.ts-up-side-rsvp i{font-size:0.85rem;}
/* Locked upcoming flyer (anonymous, Fri/Sat). Blur the art, dim the
   foot, float a sign-in panel over it; side line-up swapped for a
   sign-in note. */
/* Locked: collapse the 4:5 flyer to a compact panel so the unlock
   message is fully visible (not a tall blurred void with the heading
   clipped off-screen on mobile). */
.ts-up-featured-row.is-locked .ts-up-card__art{aspect-ratio:auto;height:clamp(280px,38vh,360px);filter:blur(16px) saturate(0.7) brightness(0.5);transform:scale(1.06);}
.ts-up-featured-row.is-locked .ts-up-card__corner{position:absolute;top:0;left:0;right:0;z-index:4;}
.ts-up-featured-row.is-locked .ts-up-card--featured{cursor:default;}
.ts-up-card--featured{position:relative;}
.ts-up-lock{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;text-align:center;padding:24px;text-decoration:none;color:#fff;background:linear-gradient(180deg,rgba(13,11,9,0.35),rgba(13,11,9,0.6));}
.ts-up-lock-ico{width:54px;height:54px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:rgba(31,140,140,0.85);color:#fff;font-size:1.3rem;margin-bottom:6px;}
.ts-up-lock-h{font-family:var(--slab);font-weight:400;font-size:1.25rem;letter-spacing:0.01em;}
.ts-up-lock-sub{font-family:var(--mono);font-size:0.62rem;letter-spacing:0.12em;text-transform:uppercase;color:rgba(245,238,221,0.85);max-width:18ch;line-height:1.5;}
.ts-up-lock:hover .ts-up-lock-ico{background:var(--ts-teal);}
.ts-up-side-locknote{display:flex;align-items:flex-start;gap:10px;text-decoration:none;color:rgba(245,238,221,0.8);font-size:0.86rem;line-height:1.55;background:rgba(31,140,140,0.1);border:1px solid rgba(31,140,140,0.28);border-radius:10px;padding:14px 14px;}
.ts-up-side-locknote i{color:var(--ts-teal-300);font-size:0.95rem;margin-top:2px;}
.ts-up-side-locknote strong{color:#fff;}
/* 75/25 holds at every width (per design ask). On narrow screens the
   25% rail just gets tighter — smaller avatars/type/padding — rather
   than collapsing to a stack. */
@media(max-width:900px){
  .ts-up-featured-row{gap:6px;}
  .ts-up-side{padding:16px 12px;gap:14px;}
  .ts-up-side-label{font-size:0.5rem;}
}
@media(max-width:560px){
  .ts-up-featured-row{gap:5px;}
  .ts-up-side{padding:14px 8px;gap:12px;border-radius:10px;}
  .ts-up-side-djs{gap:11px;}
  .ts-up-side-rsvp{font-size:0.62rem;padding:11px 8px;letter-spacing:0.08em;}
  .ts-up-side-rsvp i{display:none;}
}

@media(max-width:960px){
  /* When the headline + flyer stack vertically, the old 48px grid gap
     + 32px lede margin compounded into ~80px of dead air above the
     flyer.  Pull both in so the flyer sits visually closer to the
     "the next session." headline. */
  .ts-upcoming-inner{grid-template-columns:1fr;gap:18px;}
  .ts-upcoming-lede{margin-bottom:18px;}
  .ts-upcoming-h{margin-bottom:16px;}
  .ts-upcoming-left{padding:0;}
  .ts-up-card--featured{transform:rotate(-1deg);max-width:none;width:100%;align-self:stretch;}
}
@media(max-width:560px){
  /* On phones, kill the 260px ceiling entirely so the flyer fills the
     column width — the polaroid should feel like a poster on the
     wall, not a stamp. */
  .ts-up-card{max-width:none;}
}

/* DJ PREVIEW POPUP — sample of the artist page over a page overlay. */
.ts-djm[hidden]{display:none;}
.ts-djm{position:fixed;inset:0;z-index:1200;display:flex;align-items:flex-start;justify-content:center;padding:24px;overflow-y:auto;}
.ts-djm-overlay{position:absolute;inset:0;background:rgba(8,7,6,0.74);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);}
/* Stack wraps the card + the side-by-side photo row. Stack carries
   the max-width so card and photo row align to the same column. */
.ts-djm-stack{position:relative;z-index:1;width:100%;max-width:360px;display:flex;flex-direction:column;gap:12px;animation:ts-djm-in 0.18s ease-out;margin:auto 0;}
.ts-djm-card{position:relative;width:100%;background:var(--ts-paper);color:var(--ts-ink);border:1px solid rgba(14,14,16,0.10);border-radius:18px;overflow:hidden;box-shadow:0 32px 70px -20px rgba(0,0,0,0.6);}
@keyframes ts-djm-in{from{opacity:0;transform:translateY(10px) scale(0.98);}to{opacity:1;transform:none;}}
/* Close button — sits over the hero image, dark pill so it stays visible
   over any photo. */
.ts-djm-x{position:absolute;top:12px;right:12px;z-index:3;background:rgba(13,11,9,0.55);border:0;color:#fff;font-size:1.2rem;line-height:1;width:32px;height:32px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:background 0.15s;}
.ts-djm-x:hover{background:rgba(13,11,9,0.78);}
/* Hero band — mini version of the full profile hero (templates/events/public_artist_portal.html:841). */
.ts-djm-hero{position:relative;height:140px;background:var(--ts-paper-2);overflow:hidden;}
.ts-djm-hero img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;}
.ts-djm-hero img:not([src]){opacity:0;}
.ts-djm-hero-grad{position:absolute;inset:auto 0 0 0;height:55%;background:linear-gradient(to bottom,rgba(236,230,216,0) 0%,var(--ts-paper) 100%);pointer-events:none;}
/* No-hero fallback — brand-aligned teal gradient instead of an empty band. */
.ts-djm-card--no-hero .ts-djm-hero{background:linear-gradient(135deg,var(--ts-teal) 0%,var(--ts-teal-700,#0F5F62) 100%);}
.ts-djm-card--no-hero .ts-djm-hero-grad{background:linear-gradient(to bottom,rgba(15,95,98,0) 0%,var(--ts-paper) 100%);}
/* Avatar — overlaps hero/body seam, mirrors the full profile's avatar-wrap. */
.ts-djm-avatar-wrap{position:relative;z-index:2;margin-top:-36px;padding:0 22px;display:flex;}
.ts-djm-av{width:72px;height:72px;border-radius:50%;overflow:hidden;background:var(--ts-paper-2);border:4px solid var(--ts-paper);box-shadow:0 6px 24px rgba(0,0,0,0.18);display:flex;align-items:center;justify-content:center;flex:0 0 auto;}
.ts-djm-av img{width:100%;height:100%;object-fit:cover;}
.ts-djm-av.is-empty{background:rgba(31,140,140,0.16);}
.ts-djm-body{padding:12px 22px 20px;}
.ts-djm-name{font-family:var(--slab);font-weight:400;font-size:1.5rem;line-height:1.1;letter-spacing:-0.01em;color:var(--ts-ink);margin-top:6px;}
.ts-djm-genre{font-family:var(--mono);font-size:0.62rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-teal);margin-top:6px;}
.ts-djm-cta{display:inline-flex;align-items:center;gap:8px;background:var(--ts-teal);color:#fff;font-family:var(--mono);font-size:0.68rem;font-weight:500;letter-spacing:0.18em;text-transform:uppercase;padding:13px 22px;border-radius:999px;text-decoration:none;transition:background 0.15s;margin-top:14px;}
.ts-djm-cta:hover{background:var(--ts-teal-700,#0F5F62);}
.ts-djm-cta .bi{font-size:0.95rem;line-height:1;letter-spacing:0;}
/* Side-by-side photo row — two latest gallery images. Default 50/50
   via flex-grow:1 on each; tapping one bumps it to flex-grow:3 which
   gives the 75/25 ratio. flex-grow is the property being transitioned
   so the squish reads as one coordinated motion. Container holds a
   fixed height; tiles are buttons full of cover-fit imagery. */
.ts-djm-photo-row{display:flex;gap:8px;height:120px;width:100%;}
.ts-djm-photo-row[hidden]{display:none;}
.ts-djm-photo{flex:1 1 0;min-width:0;height:100%;padding:0;border:0;border-radius:14px;overflow:hidden;background:var(--ts-paper-2);cursor:pointer;box-shadow:0 16px 36px -16px rgba(0,0,0,0.55);transition:flex-grow 0.35s cubic-bezier(0.4,0,0.2,1);}
.ts-djm-photo img{width:100%;height:100%;object-fit:cover;display:block;}
.ts-djm-photo img:not([src]){opacity:0;}
.ts-djm-photo[hidden]{display:none;}
.ts-djm-photo:focus-visible{outline:2px solid var(--ts-teal);outline-offset:2px;}
.ts-djm-photo.is-expanded{flex-grow:3;}
@media(max-width:480px){
  .ts-djm-stack{max-width:none;}
  .ts-djm-hero{height:120px;}
  .ts-djm-avatar-wrap{margin-top:-30px;padding:0 18px;}
  .ts-djm-av{width:64px;height:64px;border-width:3px;}
  .ts-djm-body{padding:10px 18px 18px;}
  .ts-djm-name{font-size:1.3rem;}
  .ts-djm-photo-row{height:104px;}
}

/* CHOOSER MODAL — opens when an event card is clicked. Two big options:
   RSVP (door list) vs Reserve a Table. Picking either passes the event id
   through to the existing #ts-rsvp-modal with the right default-type. */
.ts-chooser-card{background:var(--ts-paper-hi);color:var(--ts-ink);max-width:580px;width:92%;padding:24px 28px 26px;position:relative;border:1px solid rgba(14,14,16,0.12);box-shadow:0 32px 60px -18px rgba(0,0,0,0.5);}
/* Full-bleed inside the chooser card — let the flyer breathe so the
   poster art carries the modal instead of getting boxed into a 260px
   letterbox. Caps at 38vh so the two option cards underneath still
   fit above the fold on a typical mobile viewport. */
.ts-chooser-flyer{display:none;width:100%;max-height:38vh;overflow:hidden;background:var(--ts-ink);margin:0 auto 18px;border-radius:10px;}
.ts-chooser-flyer.is-shown{display:block;}
.ts-chooser-flyer img{display:block;width:100%;height:auto;max-height:38vh;object-fit:contain;}
.ts-chooser-tag{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:14px;display:flex;align-items:center;gap:10px;}
.ts-chooser-tag::before{content:'';width:24px;height:1px;background:var(--ts-teal);}
.ts-chooser-h{font-family:var(--slab);font-weight:800;font-size:clamp(1.6rem,3vw,2.2rem);line-height:1.05;letter-spacing:-0.01em;margin-bottom:24px;color:var(--ts-ink);}
.ts-chooser-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
/* Keep RSVP + Reserve-a-Table side-by-side at every viewport so the
   flyer above gets to be the dominant visual instead of being shoved
   above a tall stack of stacked option cards on phones. Tighten gap
   + padding on narrow viewports so two cards still fit comfortably. */
.ts-chooser-options{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
@media(max-width:520px){
  .ts-chooser-options{gap:10px;}
}
.ts-chooser-opt{text-align:left;background:var(--ts-paper-2);border:1px solid rgba(14,14,16,0.14);padding:22px 20px;cursor:pointer;display:flex;flex-direction:column;gap:8px;transition:background 0.15s,border-color 0.15s,transform 0.15s;font-family:var(--body);color:var(--ts-ink);min-width:0;}
@media(max-width:520px){.ts-chooser-opt{padding:16px 14px;}}
.ts-chooser-opt:hover{background:var(--ts-ink);color:#fff;border-color:var(--ts-ink);transform:translateY(-2px);}
.ts-chooser-opt:hover .ts-chooser-opt-num{color:var(--ts-teal-300);}
.ts-chooser-opt:hover .ts-chooser-opt-body{color:rgba(245,238,221,0.75);}
.ts-chooser-opt-num{font-family:var(--mono);font-size:0.55rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);font-weight:600;}
.ts-chooser-opt-name{font-family:var(--slab);font-weight:800;font-size:1.4rem;line-height:1.05;letter-spacing:-0.01em;}
.ts-chooser-opt-body{font-size:0.85rem;line-height:1.55;color:var(--ts-ink-soft);}

/* Gradient backdrop for the info modal — applies only to the rsvp modal
   when opened via the chooser (or anywhere else), so the form sits on a
   warm rust→teal gradient rather than the solid dark scrim. */
#ts-rsvp-modal .ts-modal-scrim{background:radial-gradient(ellipse at 22% 18%,rgba(31,140,140,0.45),rgba(14,14,16,0.85) 55%),radial-gradient(ellipse at 82% 82%,rgba(63,124,124,0.38),transparent 60%),rgba(14,14,16,0.92);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);}

/* Chooser modal — page-level scrim stays a flat dark overlay so the
   site behind the modal feels like a normal dimmed page. The flyer
   colour wash lives INSIDE the card (in .ts-chooser-flyer below) so
   the black letterbox bars beside the contained flyer image become a
   blurred copy of the flyer instead of solid black. */
#ts-event-chooser .ts-modal-scrim{background:rgba(14,14,16,0.78);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);}
#ts-event-chooser .ts-chooser-card{position:relative;z-index:2;}

/* In-card flyer panel — the actual flyer is `object-fit:contain` so it
   keeps its aspect ratio; the leftover space on the left/right (or top/
   bottom for ultra-wide flyers) gets the same flyer painted as a
   blurred cover backdrop. */
#ts-event-chooser .ts-chooser-flyer{position:relative;isolation:isolate;}
#ts-event-chooser .ts-chooser-flyer.is-shown::before{
  content:'';position:absolute;inset:0;z-index:0;
  background-image:var(--ts-chooser-bg);
  background-repeat:no-repeat;background-position:center;background-size:cover;
  filter:blur(22px) saturate(1.15) brightness(0.85);
  -webkit-filter:blur(22px) saturate(1.15) brightness(0.85);
  transform:scale(1.18);  /* hide blur edges that bleed past the panel */
  pointer-events:none;
}
#ts-event-chooser .ts-chooser-flyer img{position:relative;z-index:1;}

/* VENUE NETWORK — same dark-card layout as .ts-upcoming, but each card
   is a partner venue with avatar + role + visit link. */
.ts-network{background:var(--ts-ink);color:#fff;padding:72px 32px;position:relative;overflow:hidden;margin:0 24px 32px;border-radius:22px;}
.ts-network::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.04) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
.ts-network-inner{max-width:1340px;margin:0 auto;display:grid;grid-template-columns:1fr 1.2fr;gap:80px;align-items:center;position:relative;z-index:1;}
.ts-network-left{padding:8px 0;}
.ts-network-eyebrow{font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:24px;display:flex;align-items:center;gap:12px;}
.ts-network-eyebrow::before{content:'';width:36px;height:1px;background:var(--ts-teal);}
.ts-network-h{font-family:var(--slab);font-weight:800;font-size:clamp(2.2rem,4.4vw,3.8rem);line-height:0.98;letter-spacing:-0.02em;color:#fff;margin-bottom:24px;}
.ts-network-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal-300);}
.ts-network-h em::after{content:'.';color:var(--ts-teal-300);}
.ts-network-lede{max-width:440px;color:rgba(245,238,221,0.7);font-size:0.95rem;line-height:1.85;margin-bottom:28px;}
.ts-network-link{display:inline-flex;align-items:center;font-family:var(--mono);font-size:0.7rem;letter-spacing:0.2em;text-transform:uppercase;color:#fff;text-decoration:none;padding-bottom:6px;border-bottom:1px solid var(--ts-teal);transition:color 0.2s;}
.ts-network-link:hover{color:var(--ts-teal-300);}
.ts-network-stack{display:flex;flex-direction:column;gap:14px;}
.ts-network-card{position:relative;background:var(--ts-paper-hi);color:var(--ts-ink);border:1px solid rgba(14,14,16,0.12);overflow:hidden;text-decoration:none;display:block;transition:transform 0.3s cubic-bezier(0.5,0.1,0.2,1),box-shadow 0.3s;box-shadow:0 18px 36px -20px rgba(0,0,0,0.55),0 4px 10px rgba(0,0,0,0.18);border-radius:22px;}
.ts-network-card:hover{transform:translateY(-3px) rotate(0)!important;box-shadow:0 26px 48px -20px rgba(0,0,0,0.65);}
.ts-network-card--featured{transform:rotate(-1deg);}
.ts-network-card:not(.ts-network-card--featured):nth-of-type(2n){transform:rotate(1.4deg);align-self:flex-end;width:88%;}
.ts-network-card:not(.ts-network-card--featured):nth-of-type(2n+1){transform:rotate(-1.4deg);align-self:flex-start;width:88%;}
.ts-network-card__corner{display:flex;justify-content:space-between;align-items:center;padding:16px 22px 0;font-family:var(--mono);font-size:0.55rem;letter-spacing:0.22em;text-transform:uppercase;}
.ts-network-card__tag{color:var(--ts-teal);font-weight:600;}
.ts-network-card__num{color:var(--ts-ink-mute);}
.ts-network-card__body{display:flex;align-items:center;gap:18px;padding:18px 22px 14px;}
.ts-network-card__avatar{width:62px;height:62px;border-radius:50%;background:radial-gradient(circle at 30% 30%,var(--ts-teal-mute),var(--ts-ink) 75%);display:flex;align-items:center;justify-content:center;font-family:var(--slab);font-weight:900;font-size:1.1rem;color:#fff;letter-spacing:0.04em;flex:0 0 auto;overflow:hidden;border:1px solid rgba(14,14,16,0.18);}
.ts-network-card--featured .ts-network-card__avatar{background:radial-gradient(circle at 30% 30%,var(--ts-teal-300),var(--ts-ink) 75%);}
.ts-network-card__avatar img{width:100%;height:100%;object-fit:cover;display:block;}
.ts-network-card__meta{flex:1 1 auto;}
.ts-network-card__name{font-family:var(--slab);font-weight:800;font-size:1.4rem;line-height:1.05;letter-spacing:-0.005em;color:var(--ts-ink);margin-bottom:4px;}
.ts-network-card__role{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-mute);}
.ts-network-card__bottombar{display:flex;justify-content:space-between;padding:12px 22px;border-top:1px solid rgba(14,14,16,0.08);font-family:var(--mono);font-size:0.55rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);}
@media(max-width:960px){
  .ts-network-inner{grid-template-columns:1fr;gap:40px;}
  .ts-network-card--featured,
  .ts-network-card:not(.ts-network-card--featured):nth-of-type(2n),
  .ts-network-card:not(.ts-network-card--featured):nth-of-type(2n+1){transform:rotate(0);width:100%;align-self:auto;}
}
@media(max-width:780px){.ts-network{margin:0 12px 18px;border-radius:22px;padding:48px 22px;}}

/* Season at a glance — cream strip after the next-session card.
   Horizontal scroller of compact Thursday tiles; first one is the
   live week (rust pill), the rest carry a small Members lock chip. */
.ts-season{background:var(--ts-paper-hi);padding:56px 0 64px;position:relative;border-top:1px solid rgba(14,14,16,0.06);border-bottom:1px solid rgba(14,14,16,0.06);}
/* Keep the head + RSVP CTA inset from the edge; only the date rail
   bleeds full-width so users can swipe past the screen edges. */
.ts-season-inner > .ts-season-head,
.ts-season-inner > .ts-season-foot{padding-left:24px;padding-right:24px;}
.ts-season::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(14,14,16,0.04) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
.ts-season-inner{max-width:1340px;margin:0 auto;position:relative;}
/* Season section is centred per brand-kit pre-header pattern — eyebrow
   chip + mono kicker centred, headline centred, lede centred under
   the headline, date rail centred, RSVP CTA centred below. */
.ts-season-head{margin-bottom:26px;text-align:center;display:flex;flex-direction:column;align-items:center;}
.ts-season-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-teal-700);margin-bottom:14px;display:inline-flex;align-items:center;gap:10px;}
.ts-season-eyebrow::before{content:'';width:22px;height:1.5px;background:var(--ts-teal);}
.ts-season-h{font-family:var(--display);font-weight:400;font-size:clamp(2rem,4.4vw,3.4rem);line-height:0.98;letter-spacing:-0.01em;color:var(--ts-ink);margin:0 auto 12px;}
.ts-season-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal-700);font-size:1em;letter-spacing:0;}
.ts-season-h em::after{content:'.';color:var(--ts-teal-700);}
.ts-season-lede{max-width:520px;color:var(--ts-ink-soft);font-size:0.95rem;line-height:1.7;margin:0 auto;}
.ts-season-rail-wrap{position:relative;}
/* Rail is full-bleed: 24px outer gutter at the row start/end so the
   first/last tile breathes but the rail itself goes edge-to-edge so
   mobile swipes hit a wide scroll area. Arrows are desktop-only
   (hidden under 780px) since touch swipe is the native gesture. */
.ts-season-rail{
  display:flex; gap:12px; overflow-x:auto;
  margin:0 56px; padding:8px 6px 12px;
  justify-content:center;
  scrollbar-width:none; -ms-overflow-style:none;
  scroll-snap-type:x proximity; scroll-behavior:smooth;
  /* pan-y, not pan-x: horizontal is arrow-driven now, so a finger on
     the rail must scroll the PAGE up/down (pan-x trapped vertical
     gestures here and froze the page). */
  -webkit-overflow-scrolling:touch; touch-action:pan-y;
  overscroll-behavior-x:contain;
}
/* Once the rail overflows the viewport, fall back to flex-start so
   pills line up at the left edge instead of getting clipped on both
   sides by `justify-content:center`. The `:has(>:nth-child(...))`
   query enables this only when there are enough tiles to overflow. */
@media(max-width:780px){
  .ts-season-rail{
    justify-content:flex-start;
    margin:0 52px;
    padding:8px 4px 12px;
    scroll-snap-type:x proximity;
  }
}
.ts-season-rail::-webkit-scrollbar{display:none;}
.ts-season-arrow{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:40px; height:40px; border-radius:50%;
  background:var(--ts-paper-hi); color:var(--ts-ink);
  border:1px solid rgba(14,14,16,0.14);
  display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer; font-size:1rem; line-height:1;
  box-shadow:0 8px 18px -10px rgba(14,14,16,0.35);
  transition:background 0.15s, color 0.15s, border-color 0.15s, opacity 0.15s, transform 0.1s;
}
.ts-season-arrow:hover{background:var(--ts-teal); color:#fff; border-color:var(--ts-teal);}
.ts-season-arrow:active{transform:translateY(-50%) scale(0.94);}
/* Arrows live in the wrap's side gutters (padding:0 56px), beside the
   rail — never over a tile, so they can't cover any letters even as
   tiles scroll past. Shown at every width (arrows replace swipe). */
.ts-season-arrow--prev{left:6px;}
.ts-season-arrow--next{right:6px;}
.ts-season-arrow.is-disabled{opacity:0.35; pointer-events:none;}
@media(max-width:560px){
  .ts-season-rail{margin:0 44px;}
  .ts-season-arrow{width:34px; height:34px; font-size:0.85rem;}
  .ts-season-arrow--prev{left:5px;}
  .ts-season-arrow--next{right:5px;}
}
.ts-season-tile{
  flex:0 0 auto; min-width:128px;
  display:flex; flex-direction:column; align-items:flex-start; gap:4px;
  padding:18px 16px 14px;
  background:var(--ts-paper); color:var(--ts-ink);
  border:1px solid rgba(14,14,16,0.10); border-radius:14px;
  text-decoration:none; scroll-snap-align:start;
  transition:transform 0.15s, border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.ts-season-tile:hover{
  transform:translateY(-2px);
  border-color:var(--ts-teal); box-shadow:0 14px 28px -16px rgba(31,140,140,0.45);
}
.ts-season-tile-day{
  font-family:var(--mono); font-size:0.6rem; letter-spacing:0.22em;
  text-transform:uppercase; color:var(--ts-ink-mute);
}
.ts-season-tile-num{
  font-family:var(--slab); font-weight:900;
  font-size:clamp(2.2rem,5vw,2.8rem); line-height:0.9; letter-spacing:-0.02em;
  color:var(--ts-ink);
}
.ts-season-tile-month{
  font-family:var(--mono); font-size:0.62rem; letter-spacing:0.2em;
  text-transform:uppercase; color:var(--ts-ink-soft); margin-bottom:6px;
}
.ts-season-tile-tag{
  font-family:var(--mono); font-size:0.54rem; letter-spacing:0.18em;
  text-transform:uppercase; font-weight:500;
  padding:5px 9px; border-radius:999px;
  background:var(--ts-teal); color:#fff;
  display:inline-flex; align-items:center; gap:5px;
}
.ts-season-tile-tag--locked{
  background:transparent; color:var(--ts-ink-mute);
  border:1px solid rgba(14,14,16,0.12);
}
.ts-season-tile-tag--locked i{font-size:0.66rem;}
.ts-season-tile.is-first{
  background:linear-gradient(135deg, var(--ts-paper) 0%, rgba(31,140,140,0.10) 100%);
  border-color:rgba(31,140,140,0.35);
}
.ts-season-tile.is-locked .ts-season-tile-num,
.ts-season-tile.is-locked .ts-season-tile-month{color:var(--ts-ink-soft);}
.ts-season-tile.is-locked .ts-season-tile-day{color:rgba(14,14,16,0.32);}
.ts-season-foot{margin-top:22px;display:flex;justify-content:center;}
.ts-season-cta{
  display:inline-flex; align-items:center; gap:10px;
  padding:13px 22px; border-radius:999px;
  background:var(--ts-ink); color:#fff;
  border:1px solid var(--ts-ink); text-decoration:none;
  font-family:var(--mono); font-size:0.7rem; font-weight:500;
  letter-spacing:0.2em; text-transform:uppercase;
  transition:background 0.15s, border-color 0.15s, transform 0.1s;
}
.ts-season-cta i{font-size:1rem;}
.ts-season-cta:hover{background:var(--ts-teal); border-color:var(--ts-teal); transform:translateY(-1px);}
@media(max-width:780px){
  .ts-season{padding:42px 18px 52px;}
  .ts-season-tile{min-width:108px;padding:14px 14px 12px;}
}

/* EDITORIAL */
.ts-edt{background:var(--ts-paper-2);padding:88px 32px;border-top:1px solid rgba(14,14,16,0.1);border-bottom:1px solid rgba(14,14,16,0.1);position:relative;overflow:hidden;}
.ts-edt-corner{position:absolute;top:24px;left:32px;font-family:var(--mono);font-size:0.62rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);}
.ts-edt-corner-r{position:absolute;top:24px;right:32px;font-family:var(--mono);font-size:0.62rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);}
/* Narrow viewports: the FIG. 03 left-corner kicker and the
   "Composed in Vancouver" right-corner kicker were absolutely
   positioned at the same top edge and overlapped each other into
   a mangled string ("FIGOMPOSED THE WANGOUVER…"). Stack them: keep
   the left-kicker pinned, push the right-kicker BELOW it. */
@media(max-width:780px){
  .ts-edt-corner,.ts-edt-corner-r{
    position:static;display:block;
    padding:0 22px;font-size:0.58rem;letter-spacing:0.18em;
  }
  .ts-edt-corner{padding-top:24px;padding-bottom:4px;}
  .ts-edt-corner-r{padding-bottom:18px;}
}
.ts-edt-inner{max-width:1340px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:center;}
.ts-edt-block{background:var(--ts-ink);color:#fff;padding:48px 38px;position:relative;overflow:hidden;aspect-ratio:5/4;display:flex;flex-direction:column;justify-content:space-between;transform:rotate(0.6deg);box-shadow:0 24px 50px -20px rgba(14,14,16,0.4);}
.ts-edt-block::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.06) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
.ts-edt-block::after{content:'';position:absolute;top:0;bottom:0;left:50%;width:1px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,0.08) 50%,transparent);}
/* Flyer image variant — Instagram portrait (1080×1350 = 4:5). The default
   .ts-edt-block uses landscape 5:4 which is fine for the text block, but
   the image variant gets the flyer-native aspect AND contain (not cover)
   so the full poster shows top-to-bottom. Smaller max-width keeps it from
   dominating the editorial split. */
/* "The Residency" / "A Dose of House" flyer block — let the image
   set its own height instead of locking a 1080x1350 portrait
   container around it.  The uploaded asset isn't strictly 1080x1350,
   so the locked aspect was letterboxing cream strips above and below
   the dark flyer art.  Dropping aspect-ratio + switching the img to
   height:auto removes the gap; the cream background is no longer
   needed for that reason, but kept (now invisible) in case a future
   asset re-introduces the matte. */
.ts-edt-block--img{padding:0;background:transparent;max-width:440px;justify-self:end;box-shadow:none;}
.ts-edt-block--img::before,.ts-edt-block--img::after{display:none;}
.ts-edt-block--img > img{
  display:block;width:100%;height:auto;
  /* Blend the poster into the cream paper — multiply pushes the
     lights to paper, opacity softens the whole thing, and a
     contrast/saturate filter keeps the print readable. */
  mix-blend-mode:multiply;
  opacity:0.88;
  filter:contrast(0.95) saturate(0.88);
}
/* Hide the "A Dose of House" editorial poster on mobile — at small
   widths it crowds the editorial copy and the copy reads better on
   its own. Desktop keeps the poster as the visual anchor. */
@media (max-width: 780px){
  .ts-edt-block--img{display:none;}
}
.ts-edt-le{display:flex;gap:18px;align-items:baseline;font-family:var(--mono);font-size:0.66rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal-mute);position:relative;z-index:1;}
.ts-edt-le span{padding:5px 9px;border:1px solid rgba(245,238,221,0.18);}
.ts-edt-thurs{font-family:var(--slab);font-weight:900;font-size:clamp(3rem,5.5vw,5rem);line-height:0.92;letter-spacing:-0.015em;text-transform:uppercase;position:relative;z-index:1;margin:18px 0;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.3' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.3'/%3E%3C/svg%3E"),linear-gradient(178deg,#FAF6EE 0%,#F0E8D5 60%,#D6CDB6 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:1.5px 1px 0 rgba(31,140,140,0.22),-1px 0 0 rgba(90,150,150,0.18);}
.ts-edt-thurs em{font-style:normal;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E"),linear-gradient(178deg,#6FAFAE 0%,#1F8C8C 55%,#0F5F62 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:2px 1.5px 0 rgba(90,150,150,0.22),-1.5px 0 0 rgba(255,255,255,0.04);}
.ts-edt-musique-row{display:flex;justify-content:space-between;align-items:flex-end;position:relative;z-index:1;gap:20px;}
.ts-edt-musique{font-family:var(--mono);font-size:0.7rem;letter-spacing:0.24em;text-transform:uppercase;color:var(--ts-cream);padding:7px 12px;border:1px solid rgba(245,238,221,0.3);}
.ts-edt-bars{display:flex;gap:4px;}
.ts-edt-bars .b{width:18px;height:46px;}
.ts-edt-bars .b.t{background:var(--ts-teal);}
.ts-edt-bars .b.r{background:var(--ts-teal);height:38px;}
.ts-edt-bars .b.c{background:var(--ts-cream);height:30px;}
.ts-edt-bars .b.t2{background:var(--ts-teal-deep);height:52px;}
.ts-edt-copy h3{font-family:var(--slab);font-weight:800;font-size:clamp(2rem,3.4vw,3rem);line-height:1;letter-spacing:-0.02em;color:var(--ts-ink);margin-bottom:24px;}
.ts-edt-copy h3 em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
.ts-edt-copy p{font-size:1rem;line-height:1.78;color:var(--ts-ink-soft);margin-bottom:18px;max-width:480px;}
/* Hello Goodbye signature → mask-tinted brand logo, inked black so it
   reads as a quiet signature mark rather than a second rust accent.
   Wrapped in an anchor pointing at hg.therapysound.ca. */
.ts-hg-sig{
  display:block;
  width:clamp(120px,16vw,180px);
  height:clamp(48px,6vw,72px);
  margin-top:14px;
  background-color:var(--ts-ink);
  -webkit-mask-image:url("https://imagedelivery.net/DMKHMoCI4OT1MdcrbL1WlA/87a3cd7e-9f3b-43ea-84be-a1bfe2bda300/headlogo");
  mask-image:url("https://imagedelivery.net/DMKHMoCI4OT1MdcrbL1WlA/87a3cd7e-9f3b-43ea-84be-a1bfe2bda300/headlogo");
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:left center;mask-position:left center;
  -webkit-mask-size:contain;mask-size:contain;
  transition:opacity 0.18s ease, background-color 0.18s ease;
}
a.ts-hg-sig-link{display:inline-block;text-decoration:none;}
a.ts-hg-sig-link:hover .ts-hg-sig{opacity:0.78;}
a.ts-hg-sig-link:focus-visible{outline:2px solid var(--ts-ink);outline-offset:4px;}
.ts-hg-cred{font-family:var(--mono);font-size:0.62rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);margin-top:18px;display:block;}
.ts-hg-visit-btn{display:inline-block;margin-top:18px;font-family:var(--mono);font-size:0.66rem;font-weight:500;letter-spacing:0.16em;text-transform:uppercase;color:var(--ts-teal);text-decoration:none;border-bottom:1px solid rgba(31,140,140,0.35);padding-bottom:2px;transition:color 0.15s,border-color 0.15s;}
.ts-hg-visit-btn:hover{color:var(--ts-teal-700,#0F5F62);border-color:var(--ts-teal-700,#0F5F62);}

/* FOOTER */
footer.ts-foot{background:var(--ts-ink);color:#fff;padding:80px 32px 38px;position:relative;overflow:hidden;}
/* Mobile: the body has padding-bottom:74px (from the bottom-nav
   partial) to keep scrollable content above the fixed nav. That
   padding rendered as a cream strip below the dark footer. Extend
   the footer's own bottom padding so the dark surface bleeds all
   the way down to (and behind) the bottom-nav — body still gets the
   74px buffer at the bottom; the dark just covers it. */
@media(max-width:767px){
  footer.ts-foot{padding-bottom:calc(38px + 74px);margin-bottom:-74px;}
}
footer.ts-foot::before{content:'';position:absolute;inset:0;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.06) 0.5px,transparent 1px);background-size:4px 4px;pointer-events:none;}
footer.ts-foot::after{content:'';position:absolute;top:0;bottom:0;left:50%;width:1px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,0.06) 50%,transparent);pointer-events:none;}
.ts-foot-inner{max-width:1340px;margin:0 auto;position:relative;z-index:1;}
.ts-foot-h{font-family:var(--slab);font-weight:900;font-size:clamp(3rem,8vw,7rem);line-height:0.88;letter-spacing:-0.02em;text-transform:uppercase;margin-bottom:6px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='280' height='280' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E"),linear-gradient(178deg,#A6CACA 0%,#82B0B0 55%,#5C8585 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:2.5px 2px 0 rgba(31,140,140,0.28),-2px 0 0 rgba(255,255,255,0.04);}
.ts-foot-h em{font-style:normal;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='280' height='280' filter='url(%23n)' opacity='0.36'/%3E%3C/svg%3E"),linear-gradient(178deg,#6FAFAE 0%,#1F8C8C 55%,#0F5F62 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;text-shadow:2.5px 2px 0 rgba(90,150,150,0.24),-2px 0 0 rgba(255,255,255,0.04);}
.ts-foot-sub{font-family:var(--mono);font-size:0.78rem;letter-spacing:0.24em;text-transform:uppercase;color:var(--ts-cream);margin-bottom:54px;}
.ts-foot-cols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:36px;padding-top:42px;border-top:1px solid rgba(255,255,255,0.12);}
.ts-foot-col-h{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.24em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:16px;}
.ts-foot-col ul{list-style:none;display:flex;flex-direction:column;gap:9px;}
.ts-foot-col a,.ts-foot-link-btn{font-size:0.85rem;color:rgba(245,238,221,0.7);text-decoration:none;transition:color 0.15s;}
.ts-foot-link-btn{background:transparent;border:0;padding:0;cursor:pointer;font-family:var(--body);text-align:left;}
.ts-foot-col a:hover,.ts-foot-link-btn:hover{color:#fff;}
.ts-foot-tag{font-size:0.85rem;color:rgba(245,238,221,0.7);line-height:1.6;max-width:280px;}
.ts-foot-bottom{margin-top:46px;padding-top:24px;border-top:1px solid rgba(255,255,255,0.12);display:flex;justify-content:space-between;align-items:center;font-family:var(--mono);font-size:0.62rem;letter-spacing:0.2em;text-transform:uppercase;color:rgba(245,238,221,0.5);flex-wrap:wrap;gap:14px;}
.ts-foot-soc{display:flex;gap:10px;}
.ts-foot-soc a{width:36px;height:36px;border:1px solid rgba(245,238,221,0.2);border-radius:50%;display:flex;align-items:center;justify-content:center;color:rgba(245,238,221,0.78);text-decoration:none;transition:all 0.15s;}
.ts-foot-soc a i{font-size:1rem;line-height:1;}
.ts-foot-soc a:hover{border-color:var(--ts-teal);color:var(--ts-teal);background:rgba(31,140,140,0.08);}

/* PERSONAL BLOCK — Your Next Session (logged-in only) */
.ts-mine{background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:22px 26px;margin-bottom:36px;display:grid;grid-template-columns:1fr auto;gap:24px;align-items:center;position:relative;overflow:hidden;}
.ts-mine::before{content:'';position:absolute;top:0;left:0;width:80px;height:3px;background:var(--ts-teal);}
.ts-mine-tag{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-teal);margin-bottom:8px;}
.ts-mine-h{font-family:var(--slab);font-weight:800;font-size:1.5rem;letter-spacing:0.02em;text-transform:uppercase;color:var(--ts-ink);line-height:1.05;}
.ts-mine-h em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
.ts-mine-meta{font-family:var(--mono);font-size:0.66rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-soft);margin-top:6px;}
.ts-mine-actions{display:flex;gap:10px;flex-wrap:wrap;}
.ts-mine-qr-btn{display:inline-flex;align-items:center;gap:8px;}
.ts-mine-qr-btn i{font-size:1.05rem;}
.ts-mine-fineprint{
  margin-top:10px;
  font-family:var(--mono);
  font-size:0.58rem;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--ts-ink-mute);
}
.ts-mine.empty{grid-template-columns:1fr auto;}

/* FORMS */
.ts-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:start;}
.ts-form-wrap{background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:36px 32px;position:relative;}
.ts-form-wrap::before{content:'';position:absolute;top:0;left:0;width:60px;height:3px;background:var(--ts-teal);}
.ts-form-wrap.alt::before{background:var(--ts-teal-deep);}
.ts-form-title{font-family:var(--slab);font-weight:800;font-size:1.55rem;letter-spacing:0.02em;text-transform:uppercase;color:var(--ts-ink);margin-bottom:6px;line-height:1.05;}
.ts-form-sub{font-family:var(--mono);font-size:0.62rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);margin-bottom:24px;}
.ts-form-g{margin-bottom:14px;}
.ts-form-g label{display:block;font-family:var(--mono);font-size:0.6rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--ts-ink-mute);margin-bottom:6px;}
.ts-form-g input,.ts-form-g select,.ts-form-g textarea{width:100%;background:var(--ts-paper);border:1px solid rgba(14,14,16,0.16);color:var(--ts-ink);padding:11px 14px;font-family:var(--body);font-size:0.92rem;outline:none;transition:border-color 0.18s;border-radius:0;}
.ts-form-g input:focus,.ts-form-g select:focus,.ts-form-g textarea:focus{border-color:var(--ts-teal);}
.ts-form-g textarea{resize:vertical;min-height:90px;}
.ts-form-g select{appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%235C5852' fill='none' stroke-width='1.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;}
.ts-form-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.ts-form-submit{width:100%;background:var(--ts-teal);color:#fff;border:1px solid var(--ts-teal);padding:14px;font-family:var(--mono);font-weight:500;font-size:0.7rem;letter-spacing:0.22em;text-transform:uppercase;cursor:pointer;margin-top:10px;transition:all 0.15s;}
.ts-form-submit:hover{background:var(--ts-teal-700);border-color:var(--ts-teal-700);}
.ts-form-submit:disabled{opacity:0.7;cursor:wait;}
.ts-form-wrap.alt .ts-form-submit{background:var(--ts-teal-deep);border-color:var(--ts-teal-deep);}
.ts-form-wrap.alt .ts-form-submit:hover{background:var(--ts-ink);border-color:var(--ts-ink);}
.ts-form-note{font-family:var(--mono);font-size:0.58rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);margin-top:12px;text-align:center;}
/* Optional-field marker on a label and the tiny help line that lives
   under a password / DOB-style input. Both reuse the existing mono
   eyebrow type so the visual rhythm matches the form labels above them. */
.ts-form-optional{font-family:var(--mono);font-size:0.55rem;letter-spacing:0.18em;color:var(--ts-ink-mute);text-transform:uppercase;margin-left:8px;opacity:0.7;}
.ts-form-help{font-family:var(--body);font-size:0.78rem;line-height:1.4;color:var(--ts-ink-soft);margin-top:6px;}
.ts-form-side{padding:8px 4px;}
.ts-form-side h3{font-family:var(--slab);font-weight:800;font-size:clamp(1.8rem,3vw,2.6rem);line-height:0.98;letter-spacing:-0.02em;color:var(--ts-ink);margin-bottom:18px;}
.ts-form-side h3 em{font-family:var(--serif);font-style:italic;font-weight:400;color:var(--ts-teal);}
.ts-form-side p{font-size:0.95rem;line-height:1.78;color:var(--ts-ink-soft);max-width:440px;margin-bottom:14px;}
.ts-form-bullets{list-style:none;margin-top:24px;display:flex;flex-direction:column;gap:0;}
.ts-form-bullets li{padding:18px 0;border-bottom:1px solid rgba(14,14,16,0.1);display:flex;gap:14px;align-items:flex-start;font-size:0.88rem;color:var(--ts-ink-soft);line-height:1.65;}
.ts-form-bullets li:first-child{border-top:1px solid rgba(14,14,16,0.1);}
.ts-form-bullets li strong{display:block;color:var(--ts-ink);font-weight:600;margin-bottom:3px;font-family:var(--slab);font-size:0.95rem;letter-spacing:0.04em;}
.ts-form-bullets-icon{width:28px;height:28px;border:1px solid var(--ts-teal);display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:0.68rem;color:var(--ts-teal);flex-shrink:0;margin-top:1px;}

/* MOMENTS — polaroids "taped" to the wall */
.ts-moments{display:grid;grid-template-columns:repeat(4,1fr);gap:48px;justify-items:center;padding:24px 12px 48px;}
.ts-pola{position:relative;background:var(--ts-paper-hi);padding:14px 14px 38px;width:100%;max-width:280px;box-shadow:0 24px 44px -22px rgba(14,14,16,0.4),0 4px 10px rgba(14,14,16,0.12);transition:transform 0.4s cubic-bezier(0.5,0.1,0.2,1),box-shadow 0.3s;}
.ts-pola::before{content:'';position:absolute;top:-14px;left:50%;transform:translateX(-50%) rotate(-3deg);width:78px;height:24px;background:linear-gradient(180deg,rgba(212,162,74,0.55) 0%,rgba(212,162,74,0.35) 100%);box-shadow:0 1px 3px rgba(14,14,16,0.18);border:1px dashed rgba(14,14,16,0.18);}
.ts-pola::after{content:'';position:absolute;inset:14px 14px 38px 14px;background-image:radial-gradient(circle at 0.5px 0.5px,rgba(14,14,16,0.06) 0.5px,transparent 1px);background-size:3px 3px;pointer-events:none;mix-blend-mode:multiply;}
.ts-pola:nth-child(1){transform:rotate(-3.5deg);margin-top:6px;}
.ts-pola:nth-child(2){transform:rotate(1.5deg);margin-top:-12px;}
.ts-pola:nth-child(3){transform:rotate(2.6deg);margin-top:8px;}
.ts-pola:nth-child(4){transform:rotate(-2deg);margin-top:-6px;}
.ts-pola:hover{transform:rotate(0) translateY(-6px);box-shadow:0 32px 60px -22px rgba(14,14,16,0.55),0 6px 14px rgba(14,14,16,0.18);}
.ts-pola-frame{aspect-ratio:1/1;background:var(--ts-ink);overflow:hidden;position:relative;}
.ts-pola-frame img{width:100%;height:100%;object-fit:cover;display:block;filter:contrast(1.04) saturate(0.92);}
.ts-pola-frame .ts-pola-empty{display:flex;align-items:center;justify-content:center;height:100%;color:rgba(245,238,221,0.45);font-family:var(--mono);font-size:0.62rem;letter-spacing:0.2em;text-transform:uppercase;text-align:center;padding:14px;line-height:1.7;}
.ts-pola-cap{margin-top:14px;font-family:var(--serif);font-style:italic;font-size:1rem;color:var(--ts-ink-soft);text-align:center;letter-spacing:0.005em;line-height:1.3;}
.ts-pola-meta{margin-top:4px;font-family:var(--mono);font-size:0.58rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);text-align:center;}

/* MOMENTS members-CTA card — sits below the polaroid row to say "members
   can add their own on the real Board." Same cream-paper aesthetic as
   the polaroids, with a wider full-width layout and a tape strip on top
   so it reads as another item on the wall. */
.ts-moments-cta{
  display:block;
  position:relative;
  margin:32px 28px 12px;
  padding:28px 32px 30px;
  background:var(--ts-paper-hi);
  color:var(--ts-ink);
  text-decoration:none;
  border:1px solid rgba(14,14,16,0.10);
  box-shadow:0 18px 30px -18px rgba(14,14,16,0.35),0 4px 10px rgba(14,14,16,0.10);
  transition:transform 0.18s,box-shadow 0.18s,background 0.18s;
}
.ts-moments-cta::before{
  content:'';position:absolute;top:-14px;left:50%;transform:translateX(-50%) rotate(-2deg);
  width:96px;height:22px;
  background:linear-gradient(180deg,rgba(31,140,140,0.62) 0%,rgba(31,140,140,0.45) 100%);
  box-shadow:0 1px 3px rgba(14,14,16,0.18);
}
.ts-moments-cta:hover{
  transform:translateY(-2px);
  background:var(--ts-ink);color:#fff;
  box-shadow:0 26px 48px -20px rgba(14,14,16,0.55),0 6px 14px rgba(14,14,16,0.16);
}
.ts-moments-cta:hover .ts-moments-cta-tag,
.ts-moments-cta:hover .ts-moments-cta-go{color:var(--ts-teal-300,#6FAFAE);}
.ts-moments-cta:hover .ts-moments-cta-p{color:rgba(245,238,221,0.78);}
.ts-moments-cta-tag{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:0.6rem;letter-spacing:0.22em;
  text-transform:uppercase;color:var(--ts-teal);font-weight:600;margin-bottom:10px;
}
.ts-moments-cta-tag::before{content:'';width:24px;height:1px;background:currentColor;}
.ts-moments-cta-h{
  font-family:var(--slab);font-weight:800;
  font-size:clamp(1.4rem,2.4vw,1.85rem);line-height:1.08;letter-spacing:-0.01em;
  color:inherit;margin:0 0 10px;max-width:680px;
}
.ts-moments-cta-h em{font-family:var(--serif);font-style:italic;font-weight:500;color:var(--ts-teal);}
.ts-moments-cta-p{
  font-size:0.92rem;line-height:1.6;color:var(--ts-ink-soft);
  margin:0 0 14px;max-width:640px;
}
.ts-moments-cta-go{
  display:inline-block;font-family:var(--mono);font-size:0.66rem;
  letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-teal);font-weight:600;
}
@media(max-width:780px){
  .ts-moments-cta{margin:24px 6px 6px;padding:24px 22px 24px;}
}

/* GIVEAWAYS */
.ts-gw{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;}
.ts-gw-card{background:var(--ts-paper-hi);border:1px solid rgba(14,14,16,0.1);padding:30px 28px;position:relative;transition:transform 0.18s,border-color 0.18s,box-shadow 0.18s;}
.ts-gw-card::before{content:'';position:absolute;top:0;left:0;width:60px;height:3px;background:var(--ts-mustard);}
.ts-gw-card:hover{border-color:var(--ts-mustard);transform:translateY(-2px);box-shadow:0 14px 28px -16px rgba(14,14,16,0.22);}
.ts-gw-badge{display:inline-block;background:var(--ts-mustard);color:var(--ts-ink);font-family:var(--mono);font-weight:500;font-size:0.56rem;letter-spacing:0.22em;text-transform:uppercase;padding:4px 10px;margin-bottom:14px;}
.ts-gw-name{font-family:var(--slab);font-weight:800;font-size:1.32rem;letter-spacing:0.02em;text-transform:uppercase;color:var(--ts-ink);margin-bottom:10px;line-height:1.1;}
.ts-gw-desc{font-size:0.92rem;line-height:1.7;color:var(--ts-ink-soft);margin-bottom:18px;}
.ts-gw-ends{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);}
.ts-gw-ends span{color:var(--ts-teal);}
.ts-gw-empty{padding:40px 28px;text-align:center;font-family:var(--mono);font-size:0.7rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-mute);background:var(--ts-paper-hi);border:1px dashed rgba(14,14,16,0.18);grid-column:1/-1;}

/* RESPONSIVE */
@media(max-width:1080px){
  /* Keep the 4+4 pagination model on tablet/mobile but lay each page out
     as 2x2 instead of 1x4. The slide-on-arrow animation works the same. */
  .ts-roster-page{grid-template-columns:repeat(2,1fr);}
  .ts-next-stack{grid-template-columns:1fr 1fr;}
  .ts-next-stack .ts-next-card.is-side{display:none;}
}
@media(max-width:520px){
  .ts-roster-page{grid-template-columns:repeat(2,1fr);gap:10px;}
  .ts-dj{padding:16px 12px;}
  .ts-dj-av{width:46px;height:46px;margin-bottom:12px;}
  .ts-dj-name{font-size:1rem;}
}
/* Tablet landscape / small desktop (≥981, ≤1180) — desktop layout
   still applies (hero is two-column at >980) but tighten spacing so
   iPad Pro landscape and 13" laptops don't feel airy. */
@media (min-width:981px) and (max-width:1180px){
  section.s{padding:64px 28px;}
  .ts-hero{padding:56px 28px 22px;}
  .ts-hero-grid{gap:28px;}
  .ts-hero-meta{margin-bottom:48px;}
  .ts-hero-stats{margin-top:40px;gap:22px;}
  .ts-foot-cols{grid-template-columns:1.4fr 1fr 1fr;gap:28px;}
  .ts-foot-cols > *:nth-child(4){display:none;}
}

@media(max-width:980px){
  .ts-hero{padding:48px 18px 20px;}
  .ts-hero-grid,.ts-edt-inner{grid-template-columns:1fr;gap:22px;}
  .ts-hero-copy{padding-left:0;}
  /* Per direction: on mobile the flyer reads BELOW the hero copy +
     "Next event ↓" button (DOM order stays flyer-first for desktop
     so the wide 0.75fr/1fr two-up layout is unchanged). */
  .ts-hero-copy{order:1;}
  .ts-flyer-wrap{order:2;}
  .ts-wwd{grid-template-columns:1fr;}
  .ts-foot-cols{grid-template-columns:repeat(2,1fr);}
  .ts-head-menu{display:none;}
  body::after{display:none;}
  .ts-flyer{aspect-ratio:auto;min-height:0;transform:none;}
  /* Drop the negative top margin so the flyer doesn't overlap the
     sticky header on mobile — adds 22px breathing room below the
     header chrome. */
  .ts-flyer-wrap{transform:none;margin:6px auto 0;}
  .ts-next-stack{grid-template-columns:1fr;}
  .ts-next-stack .ts-next-card.is-tall{display:none;}
  section.s{padding:64px 24px;}
}
@media(max-width:980px){
  .ts-form-grid{grid-template-columns:1fr;gap:36px;}
  /* Stack text full-width above the action button on phones — the
     "Welcome Back / No upcoming RSVPs yet" empty variant otherwise
     stays 2-column because .ts-mine.empty has higher specificity
     than the bare .ts-mine selector, leaving the headline squished
     into a narrow column next to the "RSVP for next Thursday"
     pill. */
  .ts-mine,
  .ts-mine.empty{grid-template-columns:1fr;text-align:left;}
  .ts-mine-actions{justify-content:flex-start;}
}
@media(max-width:980px){
  .ts-moments{grid-template-columns:repeat(2,1fr);gap:24px;}
}
@media(max-width:780px){
  .ts-gw{grid-template-columns:1fr;}
  .ts-form-row{grid-template-columns:1fr;}
  /* Modal forms stay 2-up so First/Last Name + Type/Party Size sit
     on one row instead of stretching the modal sky-high on phones. */
  .ts-modal-card .ts-form-row{grid-template-columns:1fr 1fr;}
  .ts-moments{grid-template-columns:repeat(2,1fr);gap:14px 10px;padding:24px 4px 36px;}
  .ts-pola{max-width:none;padding:10px 10px 28px;}
  .ts-pola:nth-child(1){transform:rotate(-3deg);margin-top:0;z-index:2;}
  .ts-pola:nth-child(2){transform:rotate(2.4deg);margin-top:18px;margin-left:-22px;z-index:1;}
  .ts-pola:nth-child(3){transform:rotate(-1.6deg);margin-top:-26px;margin-right:-12px;z-index:3;}
  .ts-pola:nth-child(4){transform:rotate(2.8deg);margin-top:6px;margin-left:-18px;z-index:1;}
  .ts-pola:nth-child(n+5){transform:rotate(-2deg);margin-top:0;}
}
@media(max-width:600px){
  .ts-roster{grid-template-columns:1fr;}
  .ts-hero-stats{grid-template-columns:1fr 1fr;gap:18px;}
  .ts-hero-meta{font-size:0.58rem;}
  .ts-edt-bars{display:none;}
  .ts-next-meta{grid-template-columns:1fr;}
  .ts-form-wrap{padding:28px 22px;}
}

/* SCROLL REVEAL */
.r{opacity:0;transform:translateY(40px);transition:opacity 0.85s cubic-bezier(0.2,0.6,0.2,1),transform 0.85s cubic-bezier(0.2,0.6,0.2,1);will-change:opacity,transform;}
.r.r-l{transform:translateX(-50px);}
.r.r-r{transform:translateX(50px);}
.r.r-zoom{transform:scale(0.94);}
.r.r-tilt{transform:rotate(-5deg) translateY(60px);}
.r.is-in{opacity:1;transform:none;}
.r.r-tilt.is-in{transform:rotate(-1.4deg);}
.r.r-edt-tilt.is-in{transform:rotate(0.6deg);}
.r-stagger > *{opacity:0;transform:translateY(32px);transition:opacity 0.7s cubic-bezier(0.2,0.6,0.2,1),transform 0.7s cubic-bezier(0.2,0.6,0.2,1);will-change:opacity,transform;}
.r-stagger.is-in > *{opacity:1;transform:none;}
.r-stagger.is-in > *:nth-child(1){transition-delay:0.05s;}
.r-stagger.is-in > *:nth-child(2){transition-delay:0.16s;}
.r-stagger.is-in > *:nth-child(3){transition-delay:0.27s;}
.r-stagger.is-in > *:nth-child(4){transition-delay:0.38s;}
.r-stagger.is-in > *:nth-child(5){transition-delay:0.49s;}
.r-stagger.is-in > *:nth-child(6){transition-delay:0.6s;}

/* LCP guarantee: the hero flyer holds the largest above-the-fold
   element (the poster <img>). It must NEVER depend on scroll-reveal
   JS — if it stays opacity:0 Lighthouse reports NO_LCP. Force it
   painted immediately on every device/JS state. Loses only the
   hero's fade/tilt entrance; everything else still animates. */
.ts-flyer-wrap.r,.ts-flyer-wrap.r.r-tilt{
  opacity:1!important;transform:none!important;
  transition:none!important;will-change:auto!important;
}
.ts-flyer-wrap.r .ts-flyer img{opacity:1!important;}

/* HERO BAR BEAT — slow + vertical */
@keyframes ts-beat-1{0%,60%,100%{transform:scaleY(1);}30%{transform:scaleY(1.32);}}
@keyframes ts-beat-2{0%,50%,100%{transform:scaleY(0.92);}22%{transform:scaleY(1.5);}}
@keyframes ts-beat-3{0%,42%,100%{transform:scaleY(1);}20%{transform:scaleY(1.22);}}
@keyframes ts-beat-4{0%,100%{transform:scaleY(0.82);}28%{transform:scaleY(1.42);}62%{transform:scaleY(0.7);}}
@keyframes ts-beat-5{0%,100%{transform:scaleY(0.95);}18%{transform:scaleY(1.6);}35%{transform:scaleY(1.05);}70%{transform:scaleY(1.22);}}
/* No keyframe animation — scroll position drives scaleY directly via
   paintBars() in the JS block. Bars hold their last position when the
   user stops scrolling and reverse when scrolling up. */

@media (prefers-reduced-motion: reduce){
  .r,.r.r-l,.r.r-r,.r.r-zoom,.r.r-tilt,.r-stagger > *,.ts-hero-h .l{opacity:1!important;transform:none!important;transition:none!important;}
  .ts-ticker-track,body::before,.ts-film,.ts-film::before,.ts-film::after{animation:none!important;}
  .ts-bar{transform:none!important;}
}

/* SECTION TOC — secondary sticky nav under the primary header (mirrors
   the linq-marketing .feat-tabs pattern). Sits below the hero in flow,
   then sticks just under the .ts-head once the user scrolls past the
   hero. Horizontally scrollable on mobile. */
/* Dancing-bar band — sits between the hero and the TOC. position:sticky
   sticks directly below the .ts-head so the bars stay visible (and
   animated by paintBars()) once the hero scrolls off. z-index is below
   the header so the header still composites in front. Uses the live
   --ts-head-h CSS var (published by therapy_head_cream.html) so this
   stays correct as the header height changes across breakpoints. */
/* Percussion bar-band — sits in normal flow between the hero and the
   TOC (visible above the TOC pill row at rest). As the user scrolls
   past the hero, the bars STICK at `top: head-h` so they pin just
   under the cream header for the rest of the page — that's the
   "snap to stop" behavior. TOC pins below the bars (head-h + 56px),
   so the stack reads: header → bars → TOC. Cream alpha + backdrop
   blur on the band so the bars don't bleed against raw page content
   underneath once they're pinned. */
/* Bar-band pins at the VERY TOP (top:0) at z-index 96, BEHIND the
   sticky header (z-index 100). The cream header is semi-transparent
   (alpha 0.42) with a backdrop blur, so the bars peek through behind
   the THERAPY SOUND wordmark instead of sitting in their own strip
   below the header. Transparent background on the band itself so
   it composites cleanly over whatever page content scrolls past. */
.ts-bar-band{position:sticky;top:0;z-index:96;
  background:var(--ts-noir, #0D0B09);overflow:hidden;
  height:var(--ts-head-h,64px);
  border-bottom:0;padding:0 32px;pointer-events:none;}
.ts-bar-band::before{content:'';position:absolute;inset:0;
  background-image:radial-gradient(circle at 0.5px 0.5px,rgba(255,255,255,0.04) 0.5px,transparent 1px);
  background-size:4px 4px;pointer-events:none;z-index:0;}
.ts-bar-band-inner{position:relative;z-index:1;}
.ts-bar-band-inner{max-width:1240px;margin:0 auto;display:flex;flex-direction:row;align-items:flex-end;justify-content:center;gap:7px;height:100%;overflow:hidden;}
/* Scope the band's bar heights to percentages so the equalizer reads
   as proportional regardless of the parent's pixel height — the
   flyer .ts-bars container keeps its fixed-pixel sizing untouched. */
.ts-bar-band-inner .ts-bar{height:auto;}
.ts-bar-band-inner .ts-bar.t{height:82%;}
.ts-bar-band-inner .ts-bar.r{height:96%;}
.ts-bar-band-inner .ts-bar.c{height:54%;}
.ts-bar-band-inner .ts-bar.t2{height:68%;}
.ts-bar-band-inner .ts-bar.r2{height:42%;}
.ts-bar-band-inner .ts-bar.c2{height:60%;}
@media(max-width:780px){.ts-bar-band{padding:0 18px;}.ts-bar-band-inner{gap:5px;}}
/* On-flyer variant: bars overlay the bottom edge of the hero image
   inside .ts-flyer-wrap. Absolute-positioned, transparent background,
   sticks out of the bottom-rounded image so the equalizer sits ON the
   poster instead of below it. */
.ts-flyer-wrap{overflow:visible;}
.ts-bar-band--on-flyer{
  position:absolute; left:0; right:0; bottom:0;
  top:auto !important;
  height:64px;
  background:transparent;
  padding:0 14px;
  pointer-events:none;
  z-index:3;
}
.ts-bar-band--on-flyer::before{display:none;}
.ts-bar-band--on-flyer .ts-bar-band-inner{
  max-width:none; gap:5px;
  justify-content:space-between;
}
/* Left half of the overlay bars sits over the "WEEKLY HOUSE
   SESSIONS" wordmark on the hero flyer. Clamp the first 6 bars
   short so they read as a baseline accent instead of obscuring the
   wordmark. Right half (last 6) keeps the full equalizer range
   over the DJ portrait. The percentages multiply with the per-class
   heights so the variation across the row stays intact. */
.ts-bar-band--on-flyer .ts-bar-band-inner .ts-bar:nth-child(-n+6){
  max-height:32%;
}
@media(min-width:981px){
  .ts-bar-band--on-flyer{height:72px; padding:0 18px;}
}

/* Stacked-sticky offset — header (which the bars hide behind) + TOC
   pill row. Anchor clicks land the section title just below the
   visible header + TOC stack. */
section.s[id],.ts-edt[id]{scroll-margin-top:calc(var(--ts-head-h, 64px) + 50px);}
@media(max-width:780px){section.s[id],.ts-edt[id]{scroll-margin-top:calc(var(--ts-head-h, 64px) + 40px);}}

/* PER-EVENT RSVP / TABLE MODAL — single shared modal opened by every
   session-card CTA (RSVP for this Session, Reserve a Table, Find Your
   Dose). Posts to /api/therapy/reservation with event_id locked in. */
.ts-modal{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;padding:20px;}
.ts-modal[hidden]{display:none;}
.ts-modal-scrim{position:absolute;inset:0;background:rgba(14,14,16,0.6);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);}
.ts-modal-card{position:relative;width:100%;max-width:540px;max-height:calc(100dvh - 80px);overflow:auto;background:var(--ts-paper-hi);padding:32px 28px 24px;border:1px solid rgba(14,14,16,0.18);box-shadow:0 24px 60px rgba(14,14,16,0.35);}
.ts-modal-x{position:absolute;top:10px;right:14px;background:transparent;border:0;font-size:1.6rem;line-height:1;color:var(--ts-ink-mute);cursor:pointer;font-family:var(--mono);padding:4px 8px;}
.ts-modal-x:hover{color:var(--ts-teal);}
.ts-modal-card .ts-form-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.ts-modal-card .ts-form-g input,.ts-modal-card .ts-form-g select,.ts-modal-card .ts-form-g textarea{width:100%;padding:10px 12px;border:1px solid rgba(14,14,16,0.18);background:var(--ts-paper);font-family:var(--body);font-size:0.92rem;color:var(--ts-ink);}
.ts-modal-card .ts-form-submit{width:100%;background:var(--ts-teal);color:#fff;font-family:var(--mono);font-size:0.72rem;font-weight:500;letter-spacing:0.2em;text-transform:uppercase;padding:14px 26px;border:1px solid var(--ts-teal);cursor:pointer;margin-top:8px;}
.ts-modal-card .ts-form-submit:hover{background:var(--ts-teal-700);}
.ts-modal-card .ts-form-submit:disabled{opacity:0.7;cursor:wait;}
.ts-modal-card .ts-form-note{font-family:var(--mono);font-size:0.6rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--ts-ink-mute);margin-top:10px;text-align:center;}
.ts-upcoming-cta,.ts-season-cta{cursor:pointer;}
.ts-back-wrap{padding:56px 32px 72px;display:flex;justify-content:center;background:var(--ts-paper);}
.ts-back-btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--mono);font-size:0.68rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--ts-ink-soft);text-decoration:none;border:1px solid rgba(14,14,16,0.18);padding:13px 26px;border-radius:999px;transition:color 0.15s,border-color 0.15s;}
.ts-back-btn:hover{color:var(--ts-teal);border-color:var(--ts-teal);}
.ts-back-btn i{font-size:0.85rem;}
