/* =========================================================================
   THE SHONEN TABLE — CREATOR HUB
   Standalone stylesheet. No framework, no build step, no dependencies.
   All sizing in px. The cloud and kunai artwork is inlined as data URIs so
   the page renders correctly even when opened straight from disk.
   ========================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

:root {
  --font-heading-family: "Archivo Black", "Arial Black", Impact, system-ui, sans-serif;
  --font-heading-weight: 400;
  --font-body-family: "Work Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

body {
  margin: 0;
  font-family: var(--font-body-family);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  max-width: 100%;
}

h1,
h2,
h3 {
  text-transform: uppercase;
}

body {
  --hub-ink: #0A0A09;
  --hub-ink-2: #121110;
  --hub-ink-3: #191715;
  --hub-cream: #F4F1EA;
  --hub-cream-dim: rgba(244, 241, 234, 0.68);
  --hub-cream-faint: rgba(244, 241, 234, 0.42);
  --hub-red: #C8102E;
  --hub-burgundy: #7E0C1E;
  --hub-gold: #E3A93B;
  --hub-line: rgba(244, 241, 234, 0.12);
  --hub-line-soft: rgba(244, 241, 234, 0.07);
  --hub-radius: 16px;
  --hub-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --hub-gutter: 18px;

  background: var(--hub-ink);
  color: var(--hub-cream);
}

/* Self-contained: don't depend on the theme's global reset for box sizing */
.tst-hub-wrap,
.tst-hub-section,
.tst-hub-rail,
.tst-hub-nav__rail,
.tst-hub-card,
.tst-hub-cta,
.tst-hub-tile,
.tst-hub-product {
  box-sizing: border-box;
}

main {
  overflow-x: clip;
}

@media screen and (min-width: 750px) {
  body {
    --hub-gutter: 28px;
    --hub-radius: 20px;
  }
}

/* ---------- shared shell ---------- */
.tst-hub-wrap {
  width: 100%;
  max-width: 1120px;
  margin-inline: auto;
  padding-inline: var(--hub-gutter);
}

.tst-hub-section {
  position: relative;
  padding-block: 30px;
}

@media screen and (min-width: 750px) {
  .tst-hub-section {
    padding-block: 44px;
  }
}

.tst-hub-section__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.tst-hub-section__title {
  margin: 0;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(21px, 5.6vw, 32px);
  line-height: 1.02;
  letter-spacing: 0.01em;
  color: var(--hub-cream);
}

.tst-hub-section__sub {
  margin: 7px 0 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--hub-cream-dim);
  max-width: 56ch;
}

.tst-hub-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--hub-cream-faint);
}

.tst-hub-eyebrow::before {
  content: "";
  width: 18px;
  height: 1px;
  background: var(--hub-red);
}

/* =========================================================================
   HERO
   ========================================================================= */
.tst-hub-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 78% 4%, rgba(200, 16, 46, 0.3) 0%, rgba(200, 16, 46, 0) 55%),
    radial-gradient(90% 70% at 4% 96%, rgba(126, 12, 30, 0.38) 0%, rgba(126, 12, 30, 0) 62%),
    linear-gradient(180deg, #0C0C0A 0%, #090908 100%);
  padding-block: 44px 26px;
  text-align: center;
}

@media screen and (min-width: 750px) {
  .tst-hub-hero {
    padding-block: 72px 40px;
  }
}

.tst-hub-hero__inner {
  position: relative;
  z-index: 2;
}

.tst-hub-hero__avatar {
  position: relative;
  display: inline-block;
  width: 104px;
  height: 104px;
  margin-bottom: 16px;
  border-radius: 24px;
  overflow: hidden;
  border: 1px solid var(--hub-line);
  box-shadow: 0 18px 44px -18px rgba(200, 16, 46, 0.75);
  background: #0F0E0D;
}

.tst-hub-hero__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media screen and (min-width: 750px) {
  .tst-hub-hero__avatar {
    width: 132px;
    height: 132px;
    border-radius: 30px;
  }
}

.tst-hub-hero__name {
  margin: 0 0 10px;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(30px, 9.2vw, 62px);
  line-height: 0.92;
  letter-spacing: -0.005em;
}

.tst-hub-hero__tagline {
  margin: 0 auto 10px;
  font-size: clamp(11px, 3.2vw, 14px);
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--hub-red);
}

.tst-hub-hero__blurb {
  margin: 0 auto;
  max-width: 44ch;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--hub-cream-dim);
}

/* social icon row */
.tst-hub-social-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.tst-hub-social-row__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--hub-line);
  background: rgba(244, 241, 234, 0.04);
  color: var(--hub-cream);
  text-decoration: none;
  transition: transform 0.25s var(--hub-ease), border-color 0.25s var(--hub-ease),
    background-color 0.25s var(--hub-ease);
}

.tst-hub-social-row__link svg {
  width: 19px;
  height: 19px;
  fill: currentColor;
}

.tst-hub-social-row__link:hover,
.tst-hub-social-row__link:focus-visible {
  border-color: var(--hub-red);
  background: rgba(200, 16, 46, 0.14);
  transform: translateY(-2px);
}

.tst-hub-social-row__link:active {
  transform: scale(0.94);
}

/* =========================================================================
   STICKY SECTION NAV
   ========================================================================= */
.tst-hub-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(10, 10, 9, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-block: 1px solid var(--hub-line-soft);
}

.tst-hub-nav__rail {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-block: 11px;
  scroll-padding-inline: var(--hub-gutter);
}

.tst-hub-nav__rail::-webkit-scrollbar {
  display: none;
}

.tst-hub-nav__chip {
  /* Grow to share the row, but never shrink below the label's own width, so
     four chips fit a 390px screen edge-to-edge and a fifth would scroll
     rather than clip. */
  flex: 1 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 12px 10px;
  border-radius: 999px;
  border: 1px solid var(--hub-line);
  background: transparent;
  color: var(--hub-cream-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.22s var(--hub-ease), border-color 0.22s var(--hub-ease),
    background-color 0.22s var(--hub-ease);
}

.tst-hub-nav__chip:hover,
.tst-hub-nav__chip:focus-visible {
  color: var(--hub-cream);
  border-color: rgba(244, 241, 234, 0.34);
}

/* Smallest phones still in use (iPhone SE and similar): tighten just enough
   that all four chips fit without a swipe. */
@media screen and (max-width: 359px) {
  .tst-hub-nav__rail {
    gap: 6px;
  }

  .tst-hub-nav__chip {
    padding: 12px 6px;
    font-size: 10.5px;
    letter-spacing: 0.02em;
  }
}

@media screen and (min-width: 560px) {
  .tst-hub-nav__chip {
    flex: none;
    padding: 12px 16px;
    font-size: 12px;
    letter-spacing: 0.1em;
  }
}

.tst-hub-nav__chip.is-active {
  color: var(--hub-cream);
  background: var(--hub-red);
  border-color: var(--hub-red);
}

/* =========================================================================
   BIG CTA CARD
   ========================================================================= */
.tst-hub-cta {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  min-height: 116px;
  border-radius: var(--hub-radius);
  border: 1px solid var(--hub-line);
  background: linear-gradient(135deg, #17100F 0%, #101010 62%);
  color: var(--hub-cream);
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.3s var(--hub-ease), border-color 0.3s var(--hub-ease),
    box-shadow 0.3s var(--hub-ease);
}

.tst-hub-cta:hover,
.tst-hub-cta:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(200, 16, 46, 0.6);
  box-shadow: 0 24px 50px -26px rgba(200, 16, 46, 0.8);
}

.tst-hub-cta:active {
  transform: scale(0.99);
}

.tst-hub-cta--accent {
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(200, 16, 46, 0.6) 0%, rgba(200, 16, 46, 0) 60%),
    linear-gradient(135deg, #7E0C1E 0%, #3A0710 58%, #140A0C 100%);
  border-color: rgba(200, 16, 46, 0.45);
}

.tst-hub-cta__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.tst-hub-cta__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.4;
}

.tst-hub-cta__icon {
  position: relative;
  z-index: 2;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  border: 1px solid var(--hub-line);
  background: rgba(10, 10, 9, 0.55);
  color: var(--hub-cream);
}

.tst-hub-cta__icon svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.tst-hub-cta__body {
  position: relative;
  z-index: 2;
  flex: 1 1 auto;
  min-width: 0;
}

.tst-hub-cta__title {
  margin: 0;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(18px, 4.8vw, 26px);
  line-height: 1.05;
}

.tst-hub-cta__sub {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--hub-cream-dim);
}

.tst-hub-cta__arrow {
  position: relative;
  z-index: 2;
  flex: none;
  font-size: 20px;
  line-height: 1;
  color: var(--hub-cream);
  transition: transform 0.3s var(--hub-ease);
}

.tst-hub-cta:hover .tst-hub-cta__arrow {
  transform: translateX(5px);
}

/* =========================================================================
   FEATURED VIDEO
   ========================================================================= */
.tst-hub-featured__card {
  position: relative;
  display: block;
  max-width: 820px;
  border-radius: var(--hub-radius);
  overflow: hidden;
  border: 1px solid var(--hub-line);
  background: #0F0E0D;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s var(--hub-ease), border-color 0.3s var(--hub-ease);
}

.tst-hub-featured__card:hover {
  transform: translateY(-3px);
  border-color: rgba(200, 16, 46, 0.55);
}

.tst-hub-featured__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #0F0E0D;
}

.tst-hub-featured__media img,
.tst-hub-featured__media iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
}

.tst-hub-featured__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 8, 7, 0) 42%, rgba(8, 8, 7, 0.85) 100%);
  pointer-events: none;
}

.tst-hub-featured__card.is-playing .tst-hub-featured__media::after,
.tst-hub-featured__card.is-playing .tst-hub-play {
  display: none;
}

.tst-hub-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  border: 1px solid rgba(244, 241, 234, 0.4);
  background: rgba(200, 16, 46, 0.92);
  color: #fff;
  box-shadow: 0 14px 34px -12px rgba(0, 0, 0, 0.8);
  transition: transform 0.28s var(--hub-ease), background-color 0.28s var(--hub-ease);
}

.tst-hub-play svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
  margin-left: 3px;
}

.tst-hub-featured__card:hover .tst-hub-play {
  transform: translate(-50%, -50%) scale(1.08);
}

.tst-hub-featured__meta {
  position: relative;
  z-index: 2;
  padding: 16px 18px 18px;
}

.tst-hub-featured__title {
  margin: 0;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(16px, 4.4vw, 22px);
  line-height: 1.15;
}

.tst-hub-featured__desc {
  margin: 7px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--hub-cream-dim);
}

@media screen and (min-width: 990px) {
  .tst-hub-featured__meta {
    padding: 20px 24px 22px;
  }
}

/* =========================================================================
   CONTENT RAIL (horizontal scrolling video cards)
   ========================================================================= */
.tst-hub-rail {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-inline: calc(var(--hub-gutter) * -1);
  padding-inline: var(--hub-gutter);
  padding-bottom: 6px;
  scroll-padding-inline: var(--hub-gutter);
}

.tst-hub-rail::-webkit-scrollbar {
  display: none;
}

.tst-hub-card {
  position: relative;
  flex: 0 0 60vw;
  max-width: 250px;
  scroll-snap-align: start;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--hub-line);
  background: var(--hub-ink-2);
  text-decoration: none;
  color: var(--hub-cream);
  transition: transform 0.3s var(--hub-ease), border-color 0.3s var(--hub-ease);
}

@media screen and (min-width: 750px) {
  .tst-hub-card {
    flex-basis: 230px;
  }
}

/* On wide screens a handful of cards would leave a dead gap at the end of the
   rail, so let them grow to fill it. Once there are enough cards to exceed the
   width they stop growing and the rail scrolls as normal. */
@media screen and (min-width: 990px) {
  .tst-hub-card {
    flex: 1 0 200px;
    max-width: 300px;
  }
}

.tst-hub-card:hover,
.tst-hub-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(200, 16, 46, 0.55);
}

.tst-hub-card:active {
  transform: scale(0.98);
}

.tst-hub-card__media {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: #0F0E0D;
}

.tst-hub-card--wide .tst-hub-card__media {
  aspect-ratio: 16 / 9;
}

.tst-hub-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  transition: transform 0.5s var(--hub-ease);
}

.tst-hub-card:hover .tst-hub-card__media img {
  transform: scale(1.06);
}

.tst-hub-card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 8, 7, 0) 38%, rgba(8, 8, 7, 0.88) 100%);
  pointer-events: none;
}

/* Fallback tile for platforms with no public thumbnail (TikTok / Instagram) */
.tst-hub-card__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 90% at 70% 10%, rgba(200, 16, 46, 0.3) 0%, rgba(200, 16, 46, 0) 60%),
    linear-gradient(160deg, #171513 0%, #0D0C0B 100%);
}

.tst-hub-card__fallback::before {
  content: "";
  position: absolute;
  width: 74%;
  height: 74%;
  background-color: var(--hub-cream);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 140' fill='%23000000'%3E %3Cpath d='M40 92c-15 0-27-11-27-25 0-13 10-24 23-25 3-16 17-28 34-28 15 0 28 10 32 24 3-1 6-2 10-2 15 0 27 12 27 27 0 2 0 4-1 6 10 2 17 11 17 21 0 12-10 22-23 22H45c-14 0-25-11-25-24 0-11 8-20 20-23z'/%3E %3Cpath d='M150 118c-9 0-16-6-16-15 0-8 6-14 14-15 2-9 10-16 20-16 9 0 17 6 19 14 2-1 4-1 6-1 9 0 16 7 16 16 0 1 0 2-1 3 6 1 10 6 10 12 0 7-6 13-14 13H153c-8 0-15-6-15-14 0-6 5-12 12-13z' opacity='0.55'/%3E %3Cpath d='M4 118c6 2 14 1 19-3' stroke='%23000000' stroke-width='4' fill='none' stroke-linecap='round' opacity='0.5'/%3E %3Cpath d='M205 40c6 2 13 0 17-5' stroke='%23000000' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.4'/%3E %3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 140' fill='%23000000'%3E %3Cpath d='M40 92c-15 0-27-11-27-25 0-13 10-24 23-25 3-16 17-28 34-28 15 0 28 10 32 24 3-1 6-2 10-2 15 0 27 12 27 27 0 2 0 4-1 6 10 2 17 11 17 21 0 12-10 22-23 22H45c-14 0-25-11-25-24 0-11 8-20 20-23z'/%3E %3Cpath d='M150 118c-9 0-16-6-16-15 0-8 6-14 14-15 2-9 10-16 20-16 9 0 17 6 19 14 2-1 4-1 6-1 9 0 16 7 16 16 0 1 0 2-1 3 6 1 10 6 10 12 0 7-6 13-14 13H153c-8 0-15-6-15-14 0-6 5-12 12-13z' opacity='0.55'/%3E %3Cpath d='M4 118c6 2 14 1 19-3' stroke='%23000000' stroke-width='4' fill='none' stroke-linecap='round' opacity='0.5'/%3E %3Cpath d='M205 40c6 2 13 0 17-5' stroke='%23000000' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.4'/%3E %3C/svg%3E") center / contain no-repeat;
  opacity: 0.08;
}

.tst-hub-card__fallback svg {
  position: relative;
  width: 34px;
  height: 34px;
  fill: var(--hub-cream);
  opacity: 0.85;
}

.tst-hub-card__badge {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  border-radius: 999px;
  background: rgba(10, 10, 9, 0.76);
  border: 1px solid var(--hub-line);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hub-cream);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.tst-hub-card__badge svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}

.tst-hub-card__play {
  position: absolute;
  right: 9px;
  bottom: 9px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(200, 16, 46, 0.92);
  color: #fff;
  transition: transform 0.28s var(--hub-ease);
}

.tst-hub-card__play svg {
  width: 13px;
  height: 13px;
  fill: currentColor;
  margin-left: 2px;
}

.tst-hub-card:hover .tst-hub-card__play {
  transform: scale(1.1);
}

.tst-hub-card__title {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  margin: 0;
  padding: 12px 12px 13px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.28;
  color: var(--hub-cream);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* desktop arrows */
.tst-hub-arrows {
  display: none;
  gap: 8px;
}

@media screen and (min-width: 990px) {
  .tst-hub-arrows {
    display: flex;
  }
}

/* The script hides the controls when the rail has nothing to scroll. The
   display rule above is a class selector, so it would otherwise beat the
   browser's default styling for [hidden]. */
.tst-hub-arrows[hidden] {
  display: none !important;
}

.tst-hub-arrows button {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--hub-line);
  background: transparent;
  color: var(--hub-cream);
  font-size: 15px;
  cursor: pointer;
  transition: border-color 0.22s var(--hub-ease), background-color 0.22s var(--hub-ease),
    opacity 0.22s var(--hub-ease);
}

.tst-hub-arrows button:hover:not(:disabled) {
  border-color: var(--hub-red);
  background: rgba(200, 16, 46, 0.16);
}

.tst-hub-arrows button:disabled {
  opacity: 0.3;
  cursor: default;
}

/* =========================================================================
   SHOP
   ========================================================================= */
.tst-hub-shop__list {
  display: grid;
  gap: 12px;
}

@media screen and (min-width: 750px) {
  .tst-hub-shop__list--multi {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.tst-hub-product {
  position: relative;
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  align-items: stretch;
  min-height: 132px;
  gap: 0;
  border-radius: var(--hub-radius);
  overflow: hidden;
  border: 1px solid var(--hub-line);
  background: linear-gradient(135deg, #141211 0%, #0E0D0C 100%);
  color: var(--hub-cream);
  text-decoration: none;
  transition: transform 0.3s var(--hub-ease), border-color 0.3s var(--hub-ease),
    box-shadow 0.3s var(--hub-ease);
}

@media screen and (min-width: 750px) {
  .tst-hub-product {
    grid-template-columns: 210px minmax(0, 1fr);
    min-height: 210px;
  }

  /* A lone product shouldn't stretch the full page width — it reads thin.
     Two or more products use the side-by-side grid instead. */
  .tst-hub-shop__list:not(.tst-hub-shop__list--multi) .tst-hub-product {
    max-width: 640px;
  }

  .tst-hub-product__info {
    padding: 20px 24px;
    gap: 9px;
  }
}

.tst-hub-product:hover,
.tst-hub-product:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(200, 16, 46, 0.55);
  box-shadow: 0 24px 50px -28px rgba(0, 0, 0, 0.9);
}

.tst-hub-product:active {
  transform: scale(0.99);
}

/* The media panel fills its grid track edge to edge. It must NOT use
   aspect-ratio here: the row is as tall as the text beside it, and an
   aspect-ratio would then compute a width wider than the track and spill
   over the text. Width/height 100% keeps it inside the column. */
.tst-hub-product__media {
  position: relative;
  overflow: hidden;
  background: #0B0A09;
  width: 100%;
  height: 100%;
  min-width: 0;
}

.tst-hub-product__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s var(--hub-ease);
}

.tst-hub-product:hover .tst-hub-product__media img {
  transform: scale(1.05);
}

.tst-hub-product__info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  padding: 14px 15px;
  min-width: 0;
}

.tst-hub-product__name {
  margin: 0;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(15px, 4.2vw, 20px);
  line-height: 1.12;
}

.tst-hub-product__price {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--hub-cream);
}

.tst-hub-product__price s {
  margin-left: 7px;
  opacity: 0.5;
  font-weight: 500;
}

.tst-hub-product__swatches {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.tst-hub-product__swatch-count {
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hub-cream-faint);
}

.tst-hub-product__btn {
  align-self: flex-start;
  margin-top: 3px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 17px;
  border-radius: 999px;
  background: var(--hub-red);
  border: 1px solid var(--hub-red);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background-color 0.25s var(--hub-ease), box-shadow 0.25s var(--hub-ease);
}

.tst-hub-product:hover .tst-hub-product__btn {
  box-shadow: 0 10px 24px -10px rgba(200, 16, 46, 0.9);
}

.tst-hub-product__btn--soldout,
.tst-hub-product__btn--soon {
  background: transparent;
  border-color: var(--hub-line);
  color: var(--hub-cream-dim);
  cursor: default;
}

/* Store teaser: no link, so no hover lift, no pointer, and the artwork sits
   back a little to read as "not yet" rather than "broken". */
.tst-hub-product--soon {
  cursor: default;
}

.tst-hub-product--soon:hover {
  transform: none;
  border-color: var(--hub-line);
  box-shadow: none;
}

.tst-hub-product--soon .tst-hub-product__media img {
  opacity: 0.62;
  filter: saturate(0.75);
}

.tst-hub-product--soon:hover .tst-hub-product__media img {
  transform: none;
}

.tst-hub-product--soon .tst-hub-product__price {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hub-red);
}

.tst-hub-shop__empty {
  padding: 26px 18px;
  border: 1px dashed var(--hub-line);
  border-radius: var(--hub-radius);
  text-align: center;
  color: var(--hub-cream-dim);
  font-size: 14px;
}

/* A quantity/variant hint next to the price, e.g. "£60 — 2 T-Shirts". Same
   treatment as the struck-through price above: present, but visibly lighter
   than the price itself. */
.tst-hub-product__price-note {
  font-weight: 500;
  opacity: 0.7;
}

/* Small print under the buy buttons: the delivery estimate, and — while
   testMode is on in config.js — a reminder that checkout is in Stripe test
   mode, so the store never reads as fully live before it is. */
.tst-hub-shop__note {
  margin: 14px 2px 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--hub-cream-dim);
}

.tst-hub-shop__note--test {
  color: var(--hub-gold);
  font-weight: 600;
}


/* Product colour gallery -------------------------------------------------- */
.tst-hub-colorway {
  margin-top: 18px;
  padding: 16px;
  border: 1px solid var(--hub-line);
  border-radius: var(--hub-radius);
  background: linear-gradient(135deg, rgba(20,18,17,0.92), rgba(11,10,9,0.96));
}

.tst-hub-colorway__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.tst-hub-colorway__eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hub-red);
}

.tst-hub-colorway__head strong {
  font-size: 13px;
  color: var(--hub-cream);
}

.tst-hub-colorway__swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}

.tst-hub-color {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 7px 10px;
  border: 1px solid var(--hub-line);
  border-radius: 999px;
  background: rgba(255,255,255,0.03);
  color: var(--hub-cream-dim);
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
  transition: border-color .2s var(--hub-ease), background-color .2s var(--hub-ease), color .2s var(--hub-ease), transform .2s var(--hub-ease);
}

.tst-hub-color:hover,
.tst-hub-color:focus-visible,
.tst-hub-color.is-active {
  border-color: rgba(200,16,46,.72);
  background: rgba(200,16,46,.12);
  color: var(--hub-cream);
}

.tst-hub-color:active { transform: scale(.98); }

.tst-hub-color__dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 14px;
  border: 1px solid rgba(255,255,255,.28);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.14);
}
.tst-hub-color__dot--white { background:#f4f3ef; }
.tst-hub-color__dot--black { background:#111; }
.tst-hub-color__dot--blue  { background:#1556c8; }
.tst-hub-color__dot--red   { background:#c51f28; }
.tst-hub-color__dot--beige { background:#d9c39f; }
.tst-hub-color__dot--green { background:#0d6339; }

.tst-hub-colorway__views {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}

.tst-hub-colorway__views figure {
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--hub-line);
  border-radius: calc(var(--hub-radius) - 4px);
  background: #f4f4f2;
}

.tst-hub-colorway__views img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #f4f4f2;
}

.tst-hub-colorway__views figcaption {
  padding: 7px 9px;
  border-top: 1px solid rgba(255,255,255,.08);
  background: #11100f;
  color: var(--hub-cream-dim);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.tst-hub-colorway__combined { grid-column: 1 / -1; }
.tst-hub-colorway__combined img { aspect-ratio: 2 / 1; object-fit: cover; }

@media screen and (min-width: 750px) {
  .tst-hub-colorway { padding: 20px; margin-top: 20px; }
  .tst-hub-colorway__views { grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
  .tst-hub-colorway__views figure { grid-column: span 1; }
  .tst-hub-colorway__combined { grid-column: span 2 !important; }
  .tst-hub-colorway__combined img { aspect-ratio: 2 / 1; }
}

/* =========================================================================
   SOCIAL / PLATFORM TILES
   ========================================================================= */
.tst-hub-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* On the two-column (mobile) grid an odd number of tiles would leave a lonely
   half-width tile on the last row — let it take the full width instead.
   Scoped to the 2-col breakpoint: on desktop the grid is 3 wide. */
@media screen and (max-width: 749px) {
  .tst-hub-tile:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    min-height: 84px;
  }
}

@media screen and (min-width: 750px) {
  .tst-hub-tiles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
  }
}

.tst-hub-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 22px;
  min-height: 132px;
  padding: 15px;
  border-radius: var(--hub-radius);
  overflow: hidden;
  border: 1px solid var(--hub-line);
  background: linear-gradient(155deg, #151312 0%, #0D0C0B 100%);
  color: var(--hub-cream);
  text-decoration: none;
  transition: transform 0.3s var(--hub-ease), border-color 0.3s var(--hub-ease),
    background-color 0.3s var(--hub-ease);
}

.tst-hub-tile::before {
  content: "";
  position: absolute;
  right: -22%;
  bottom: -28%;
  width: 72%;
  height: 72%;
  background-color: var(--hub-cream);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 140' fill='%23000000'%3E %3Cpath d='M40 92c-15 0-27-11-27-25 0-13 10-24 23-25 3-16 17-28 34-28 15 0 28 10 32 24 3-1 6-2 10-2 15 0 27 12 27 27 0 2 0 4-1 6 10 2 17 11 17 21 0 12-10 22-23 22H45c-14 0-25-11-25-24 0-11 8-20 20-23z'/%3E %3Cpath d='M150 118c-9 0-16-6-16-15 0-8 6-14 14-15 2-9 10-16 20-16 9 0 17 6 19 14 2-1 4-1 6-1 9 0 16 7 16 16 0 1 0 2-1 3 6 1 10 6 10 12 0 7-6 13-14 13H153c-8 0-15-6-15-14 0-6 5-12 12-13z' opacity='0.55'/%3E %3Cpath d='M4 118c6 2 14 1 19-3' stroke='%23000000' stroke-width='4' fill='none' stroke-linecap='round' opacity='0.5'/%3E %3Cpath d='M205 40c6 2 13 0 17-5' stroke='%23000000' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.4'/%3E %3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 140' fill='%23000000'%3E %3Cpath d='M40 92c-15 0-27-11-27-25 0-13 10-24 23-25 3-16 17-28 34-28 15 0 28 10 32 24 3-1 6-2 10-2 15 0 27 12 27 27 0 2 0 4-1 6 10 2 17 11 17 21 0 12-10 22-23 22H45c-14 0-25-11-25-24 0-11 8-20 20-23z'/%3E %3Cpath d='M150 118c-9 0-16-6-16-15 0-8 6-14 14-15 2-9 10-16 20-16 9 0 17 6 19 14 2-1 4-1 6-1 9 0 16 7 16 16 0 1 0 2-1 3 6 1 10 6 10 12 0 7-6 13-14 13H153c-8 0-15-6-15-14 0-6 5-12 12-13z' opacity='0.55'/%3E %3Cpath d='M4 118c6 2 14 1 19-3' stroke='%23000000' stroke-width='4' fill='none' stroke-linecap='round' opacity='0.5'/%3E %3Cpath d='M205 40c6 2 13 0 17-5' stroke='%23000000' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.4'/%3E %3C/svg%3E") center / contain no-repeat;
  opacity: 0.06;
  pointer-events: none;
}

.tst-hub-tile:hover,
.tst-hub-tile:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(200, 16, 46, 0.55);
}

.tst-hub-tile:active {
  transform: scale(0.98);
}

.tst-hub-tile__icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  border: 1px solid var(--hub-line);
  background: rgba(244, 241, 234, 0.05);
  color: var(--hub-cream);
}

.tst-hub-tile__icon svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.tst-hub-tile__label {
  position: relative;
  margin: 0;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  line-height: 1.1;
}

.tst-hub-tile__handle {
  position: relative;
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--hub-cream-faint);
}

/* =========================================================================
   FOOTER
   ========================================================================= */
.tst-hub-footer {
  position: relative;
  overflow: hidden;
  margin-top: 14px;
  padding-block: 40px 34px;
  text-align: center;
  border-top: 1px solid var(--hub-line-soft);
  background: linear-gradient(180deg, #0A0A09 0%, #0D0B0B 100%);
}

.tst-hub-footer__inner {
  position: relative;
  z-index: 2;
}

.tst-hub-footer__name {
  margin: 0 0 8px;
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  font-size: clamp(19px, 5.4vw, 26px);
  line-height: 1;
}

.tst-hub-footer__tagline {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--hub-red);
}

.tst-hub-footer__legal {
  margin: 20px 0 0;
  font-size: 11.5px;
  color: var(--hub-cream-faint);
}

.tst-hub-footer__legal a {
  color: inherit;
}

/* =========================================================================
   MOTION — entrances + reduced-motion
   ========================================================================= */
.tst-hub-in {
  opacity: 0;
  transform: translate3d(0, 18px, 0) scale(0.985);
  transition: opacity 0.7s var(--hub-ease), transform 0.7s var(--hub-ease);
}

.tst-hub-in.is-in {
  opacity: 1;
  transform: none;
}

.no-js .tst-hub-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .tst-hub-in {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .tst-hub-card,
  .tst-hub-cta,
  .tst-hub-product,
  .tst-hub-tile,
  .tst-hub-social-row__link {
    transition: none;
  }
}

/* Keyboard focus stays obvious everywhere on the hub */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--hub-red);
  outline-offset: 3px;
}

/* =========================================================================
   Element display normalisation.
   Several of the elements above are <span>s (so they can sit legally inside
   the <a> cards). Spans are inline by default, which would drop their margins
   and box sizing — these rules give them the block/flex behaviour the layout
   above assumes. Sizing lives in the rules above; this block only sets display.
   ========================================================================= */
.tst-hub-cta__title,
.tst-hub-cta__sub,
.tst-hub-featured__meta,
.tst-hub-featured__desc,
.tst-hub-product__name,
.tst-hub-product__price,
.tst-hub-tile__label,
.tst-hub-tile__handle {
  display: block;
}

.tst-hub-featured__media,
.tst-hub-card__media,
.tst-hub-product__media {
  display: block;
}

.tst-hub-product__swatches {
  display: flex;
}

/* Anchored sections clear the sticky nav when jumped to */
/* Every jump target clears the sticky nav. app.js measures the nav and sets
   --hub-nav-h, so this stays correct if the nav ever changes height. */
[id] {
  scroll-margin-top: calc(var(--hub-nav-h, 68px) + 16px);
}

body {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  body {
    scroll-behavior: auto;
  }
}

/* =========================================================================
   STANDALONE EXTRAS
   ========================================================================= */

/* A section with nothing in it (e.g. you removed the featured video from
   config.js) collapses instead of leaving a dead gap. */
.tst-hub-section:empty,
.tst-hub-nav:empty {
  display: none;
}

/* Shown only if JavaScript is unavailable */
.tst-hub-noscript {
  max-width: 520px;
  margin: 0 auto;
  padding: 48px 20px;
  text-align: center;
  color: var(--hub-cream);
}

.tst-hub-noscript h1 {
  font-family: var(--font-heading-family);
  font-size: 30px;
  margin: 0 0 6px;
}

.tst-hub-noscript p {
  color: var(--hub-red);
  letter-spacing: 0.24em;
  font-size: 12px;
  font-weight: 700;
  margin: 0 0 26px;
}

.tst-hub-noscript ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.tst-hub-noscript a {
  display: block;
  padding: 15px;
  border: 1px solid var(--hub-line);
  border-radius: 14px;
  color: var(--hub-cream);
  text-decoration: none;
  font-weight: 600;
}

/* =========================================================================
   TST MOTION LAYER
   Drifting sky, rotating kunai, tilting cards, kunai cursor, slash dividers.

   Two rules keep this at 60fps:
     1. Only transform / opacity / filter are ever animated — never width,
        height, top or left, which would force the browser to re-layout.
     2. Where JavaScript and CSS both move the same thing, they act on
        different elements (JS moves the wrapper, CSS animates the child),
        so they never fight over one transform.
   ========================================================================= */

.tst-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* ---------------------------------------------------------------- the sky */
.tst-sky {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.tst-sky__cloud {
  position: absolute;
  /* Body is a true cloud grey rather than the page cream, so the pale curl
     outlines have something to sit against. The opacity multiplier puts the
     rendered brightness back where the cream version was. */
  color: #8E8C88;
  opacity: calc(var(--c-op, 0.05) * 1.63);
  will-change: transform;
  transition: opacity 0.5s var(--hub-ease), scale 0.5s var(--hub-ease);
}

.tst-sky__cloud > svg,
.tst-sky__cloud > img {
  display: block;
  width: 100%;
  height: 100%;
  animation: tst-drift var(--c-dur, 90s) ease-in-out infinite;
  animation-delay: var(--c-delay, 0s);
}

/* If effects.cloudImage is set, every cloud is a copy of that one file.
   Height is left to follow the width so the artwork keeps its exact
   proportions — it is never cropped, stretched or redrawn. The grey is a
   display-time filter, so the source file itself is untouched, and each copy
   gets its own shade from --c-grey. */
.tst-sky__cloud > img.tst-sky__img {
  height: auto;
  object-fit: contain;
  filter: grayscale(1) brightness(var(--c-grey, 1.15)) contrast(0.92);
}

/* The body carries the cloud colour; the curls are stroked in the page
   colour so they read as carved out of it, the way they are on the tee.

   These selectors must NOT be scoped to the cloud element. <use> clones the
   symbol out of <defs>, and a descendant selector would match neither the
   original nor the clone. Styling the symbol's own elements works because
   the computed values are carried into every clone — and currentColor plus
   custom properties still resolve per instance, so each cloud can have its
   own colour. */
.cloud-body {
  fill: currentColor;
}

/* Pale open spirals sitting ON the cloud, not holes punched THROUGH it.
   fill:none is what keeps them outlines — without it each spiral fills in
   solid and the cloud reads as a grey blob with black spots. */
.cloud-curls {
  fill: none;
  stroke: var(--cloud-curl, #F7F5F0);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The cluster around the hero title: closer, brighter, its own drift. */
.tst-hero-sky {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

/* The hero cluster runs brighter and closer, so its curls go a touch whiter
   to hold the same separation from the body. */
.tst-sky__cloud--hero {
  --cloud-curl: #FFFDF8;
}

/* Clouds fly rather than sit: a long sweep across, a lift, and a slight
   roll, so no two passes look quite the same. */
@keyframes tst-drift {
  0% {
    transform: translate3d(-11vw, 1.5vw, 0) rotate(-2deg);
  }
  35% {
    transform: translate3d(-1vw, -2vw, 0) rotate(1.5deg);
  }
  70% {
    transform: translate3d(9vw, 0.5vw, 0) rotate(-1deg);
  }
  100% {
    transform: translate3d(-11vw, 1.5vw, 0) rotate(-2deg);
  }
}

/* Every other cloud takes the opposite path */
.tst-sky__cloud:nth-child(even) > svg,
.tst-sky__cloud:nth-child(even) > img {
  animation-name: tst-drift-alt;
}

@keyframes tst-drift-alt {
  0% {
    transform: translate3d(10vw, -1vw, 0) rotate(2deg);
  }
  40% {
    transform: translate3d(0, 2vw, 0) rotate(-1.5deg);
  }
  75% {
    transform: translate3d(-9vw, -0.5vw, 0) rotate(1deg);
  }
  100% {
    transform: translate3d(10vw, -1vw, 0) rotate(2deg);
  }
}

/* Clouds brighten and swell as the cursor passes near them. Proximity, not
   hover — the sky ignores clicks entirely, so it can never block a link. */
.tst-sky__cloud.is-near {
  opacity: calc(var(--c-op, 0.05) * 3.4);
  scale: 1.07;
}

/* The hero cluster already runs bright, so it brightens by less — otherwise
   it goes fully opaque and starts competing with the title. */
.tst-sky__cloud--hero.is-near {
  opacity: calc(var(--c-op, 0.05) * 2.4);
}

/* --------------------------------------------------------------- the kunai */
.tst-kunai-fx {
  position: absolute;
  z-index: 0;
  color: var(--hub-gold);
  opacity: var(--k-op, 0.16);
  pointer-events: none;
  will-change: transform;
  transition: opacity 0.45s var(--hub-ease), scale 0.45s var(--hub-ease);
}

.tst-kunai-fx svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: currentColor;
  animation: tst-spin var(--k-dur, 26s) linear infinite;
}

/* A spot that uses an image file (e.g. the hero shuriken) instead of the
   drawn symbol gets the same size and the same slow, smooth spin. */
.tst-kunai-fx__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  animation: tst-spin var(--k-dur, 26s) linear infinite;
}

@keyframes tst-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Near the cursor a kunai flares and spins up. The speed change is done by
   fx.js through the animation's playback rate so it accelerates smoothly
   instead of jumping. */
.tst-kunai-fx.is-near {
  opacity: calc(var(--k-op, 0.16) * 2.6);
  scale: 1.12;
}

/* ------------------------------------------------------------ straw hat */
/* One static silhouette low in the hero corner — no spin, no drift, just
   a quiet shape sitting behind the content. */
.tst-strawhat-fx {
  position: absolute;
  z-index: 0;
  height: auto;
  color: #8E8C88;
  opacity: 0.16;
  pointer-events: none;
}

.tst-strawhat-fx svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* ------------------------------------------------------------ hero heading */
.tst-hub-hero__name {
  position: relative;
  animation: tst-aura 5s ease-in-out infinite;
  transition: text-shadow 0.4s var(--hub-ease);
}

@keyframes tst-aura {
  0%,
  100% {
    filter: drop-shadow(0 0 10px rgba(200, 16, 46, 0.18));
  }
  50% {
    filter: drop-shadow(0 0 26px rgba(200, 16, 46, 0.4));
  }
}

.tst-hub-hero__name:hover {
  text-shadow: 0 0 24px rgba(244, 241, 234, 0.4), 0 0 64px rgba(200, 16, 46, 0.5);
}

/* The taijitu standing in for the O in SHONEN */
.tst-yy {
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  vertical-align: -0.075em;
  margin: 0 0.015em;
}

.tst-yy svg {
  display: block;
  width: 100%;
  height: 100%;
  animation: tst-spin 16s linear infinite;
}

.yy-light {
  fill: var(--hub-cream);
}

.yy-dark {
  fill: #0a0a09;
}

.tst-hub-hero__name:hover .tst-yy svg {
  animation-duration: 3.5s;
}

/* --------------------------------------------------------- slash dividers */
.tst-slash > * {
  position: relative;
  z-index: 1;
}

/* A level hairline between sections. This used to be set at a slight angle,
   which made the banner above it look crooked even though the banner is
   perfectly square — so it runs straight now. */
.tst-slash::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  z-index: 1;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(200, 16, 46, 0.55) 22%,
    rgba(227, 169, 59, 0.7) 50%,
    rgba(200, 16, 46, 0.55) 78%,
    transparent
  );
  pointer-events: none;
}

.tst-slash::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(200, 16, 46, 0.05), transparent 38%);
}

/* ------------------------------------------------------- card tilt + glow */
.tst-tilt {
  transform-style: preserve-3d;
}

.tst-tilt::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    240px circle at var(--gx, 50%) var(--gy, 50%),
    rgba(200, 16, 46, 0.22),
    transparent 62%
  );
  transition: opacity 0.35s var(--hub-ease);
}

.tst-tilt.is-tilting {
  transform: perspective(1000px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg))
    translate3d(0, -6px, 0) scale(1.012);
  transition: transform 0.12s var(--hub-ease), box-shadow 0.4s var(--hub-ease),
    border-color 0.4s var(--hub-ease);
  border-color: rgba(200, 16, 46, 0.5);
  box-shadow: 0 0 0 1px rgba(200, 16, 46, 0.4), 0 28px 60px -28px rgba(200, 16, 46, 0.6);
  will-change: transform;
}

.tst-tilt.is-tilting::after {
  opacity: 1;
}

/* A TST mark that floats up as a card is held */
.tst-fx-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 5;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(10, 10, 9, 0.82);
  border: 1px solid var(--hub-line);
  color: var(--hub-gold);
  opacity: 0;
  transform: translateY(7px) scale(0.82);
  transition: opacity 0.35s var(--hub-ease), transform 0.35s var(--hub-ease);
  pointer-events: none;
}

.tst-fx-badge svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

.tst-tilt.is-tilting .tst-fx-badge {
  opacity: 1;
  transform: translateY(0) scale(1);
  animation: tst-badge-float 2.6s ease-in-out infinite;
}

@keyframes tst-badge-float {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -4px;
  }
}

/* ------------------------------------------------------------- the cursor */
body.tst-cursor-on,
body.tst-cursor-on a,
body.tst-cursor-on button,
body.tst-cursor-on .tst-hub-card,
body.tst-cursor-on .tst-hub-tile {
  cursor: none;
}

.tst-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: opacity 0.25s var(--hub-ease);
}

.tst-cursor.is-on {
  opacity: 1;
}

.tst-cursor__blade {
  display: block;
  width: 13px;
  height: 38px;
  fill: var(--hub-cream);
  transform: translate(-22%, -14%) rotate(-32deg);
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.85));
  transition: transform 0.2s var(--hub-ease), fill 0.2s var(--hub-ease);
}

.tst-cursor.is-over .tst-cursor__blade {
  transform: translate(-22%, -14%) rotate(-32deg) scale(1.25);
  fill: var(--hub-red);
}

.tst-cursor.is-down .tst-cursor__blade {
  transform: translate(-22%, -14%) rotate(-32deg) scale(0.82);
}

.tst-spark {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9998;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--hub-red);
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}

/* ------------------------------------------------ touch, small and calm */

/* No hover means no cursor and no tilt — a phone gets the sky and the
   kunai, and nothing that depends on a pointer. */
@media (hover: none), (pointer: coarse) {
  .tst-cursor,
  .tst-spark {
    display: none !important;
  }

  body.tst-cursor-on,
  body.tst-cursor-on a,
  body.tst-cursor-on button {
    cursor: auto;
  }

  .tst-tilt.is-tilting {
    transform: none;
    box-shadow: none;
  }

  .tst-tilt::after {
    display: none;
  }
}

@media screen and (max-width: 749px) {
  .tst-slash::before {
    left: -10%;
    right: -10%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tst-sky__cloud > svg,
  .tst-sky__cloud > img,
  .tst-kunai-fx svg,
  .tst-kunai-fx__img,
  .tst-yy svg,
  .tst-hub-hero__name,
  .tst-tilt.is-tilting .tst-fx-badge {
    animation: none !important;
  }

  .tst-sky__cloud.is-near,
  .tst-kunai-fx.is-near {
    scale: 1;
  }

  .tst-tilt.is-tilting {
    transform: none;
  }

  .tst-cursor,
  .tst-spark {
    display: none !important;
  }

  body.tst-cursor-on,
  body.tst-cursor-on a,
  body.tst-cursor-on button {
    cursor: auto;
  }
}
