/* ==========================================================================
   HEAT CLUB — LAYOUT & COMPONENTS
   Load order: fonts.css → tokens.css → styles.css
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset
   -------------------------------------------------------------------------- */

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

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

body,
h1, h2, h3, p, figure, blockquote, ul, ol, dl, dd {
  margin: 0;
}

ul[class] { list-style: none; padding: 0; }

img, svg { display: block; max-width: 100%; }

button, input { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--butter);
  outline-offset: 3px;
}


/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

body {
  background: var(--ivory);
  color: var(--espresso);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

::selection {
  background: var(--oxblood);
  color: var(--ivory);
}


/* --------------------------------------------------------------------------
   3. Utilities
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--gutter);
  max-width: 82rem;
}

.section {
  padding-block: var(--section-y);
}

.eyebrow {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  line-height: 1.4;
  margin: 0;
}

.display {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 60;
  font-weight: 300;
  line-height: var(--leading-display);
  letter-spacing: -0.015em;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Language ------------------------------------------------------------
   Both languages sit in the markup and one is hidden by CSS, so the page is
   correct before any JavaScript runs and both are readable by search engines.
   -------------------------------------------------------------------------- */

#site[data-lang="de"] [lang="en"],
#site[data-lang="en"] [lang="de"] { display: none; }

.langswitch {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--ivory-55);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-caps);
}

.langswitch__btn {
  background: none;
  border: 0;
  padding: 0.35rem 0.15rem;
  font-size: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
  transition: color 240ms var(--ease);
}

.langswitch__btn:hover { color: var(--ivory); }
.langswitch__btn[aria-pressed="true"] { color: var(--ivory); }

/* Film grain. Sits above everything, ignores pointer events. Masks the
   softness of an upscaled photograph and gives the page a printed feel. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.055;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Scroll reveal. The .js class is set by main.js so the page is fully
   visible if JavaScript never runs. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur) var(--ease-out-soft),
              transform var(--dur) var(--ease-out-soft);
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}


/* --------------------------------------------------------------------------
   4. Hero — composed as a magazine cover: mark at the top, headline and
      cover-line at the foot, photograph running full bleed behind.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  background: var(--oxblood);
  color: var(--ivory);
  isolation: isolate;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 46% 40%;
  transform: scale(1.06);
  animation: hero-settle 2600ms var(--ease-out-soft) 120ms both;
}

@keyframes hero-settle {
  from { transform: scale(1.10); opacity: 0.55; }
  to   { transform: scale(1.06); opacity: 1; }
}

/* Two scrims: a warm overall tint that pulls the photograph toward oxblood,
   and a directional wash that builds darkness under the headline. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, var(--oxblood) 2%, rgba(59, 5, 16, 0.62) 30%, rgba(59, 5, 16, 0.06) 66%, rgba(59, 5, 16, 0.26) 100%),
    linear-gradient(105deg, rgba(42, 3, 11, 0.62) 0%, rgba(42, 3, 11, 0.04) 46%, rgba(42, 3, 11, 0.30) 100%);
}

/* The masthead is lifted out of the content flow so it can sit over the
   photograph at every size — including mobile, where the image occupies its
   own band and the copy drops below it. */
.hero__masthead {
  position: absolute;
  inset-inline: 0;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block-start: clamp(1.75rem, 4vh, 3rem);
}

.hero__inner {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-block: clamp(1.75rem, 4vh, 3rem) clamp(2.5rem, 6vh, 4.5rem);
}

.hero__logo {
  width: clamp(3.4rem, 5.5vw, 5rem);
  flex: none;
}

.hero__logo img { width: 100%; height: auto; }

.hero__content { max-width: none; }

/* Held to roughly the width of "Strongest Self." so the headline breaks as
   two deliberate lines rather than wherever the viewport happens to fall. */
.hero__title {
  font-size: var(--step-5);
  max-width: 16ch;
  margin-bottom: clamp(1.25rem, 2.6vw, 2rem);
}

.hero__lede {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--ivory-70);
  max-width: 34ch;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}

/* Below 48rem the photograph gets its own band and the copy sits on solid
   oxblood underneath — a full-bleed crop this wide would otherwise have to
   zoom far past its native resolution to fill a tall phone screen. */
@media (max-width: 47.99rem) {
  .hero { min-height: 0; }

  .hero__media {
    position: relative;
    height: 46svh;
    min-height: 15rem;
  }

  .hero__media img { object-position: 58% 42%; }

  .hero__media::after {
    background: linear-gradient(to top, var(--oxblood) 2%, rgba(59, 5, 16, 0.30) 55%, rgba(59, 5, 16, 0.40) 100%);
  }

  .hero__inner {
    padding-block: clamp(2.25rem, 5vh, 3rem) clamp(3rem, 7vh, 4rem);
  }
}


/* --------------------------------------------------------------------------
   5. Waiting-list form
   -------------------------------------------------------------------------- */

.signup { max-width: 36rem; }

.signup__row {
  display: flex;
  align-items: stretch;
  gap: 0;
  border-bottom: 1px solid var(--ivory-16);
  transition: border-color 240ms var(--ease);
}

.signup__row:focus-within { border-bottom-color: var(--butter); }

.signup__input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0.85rem 0.5rem 0.85rem 0;
  font-size: var(--step-0);
  letter-spacing: 0.01em;
}

.signup__input::placeholder { color: var(--ivory-55); }
.signup__input:focus { outline: none; }

.signup__submit {
  flex: none;
  background: none;
  border: 0;
  padding: 0.85rem 0 0.85rem 1rem;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: opacity 240ms var(--ease);
}

.signup__submit:hover { opacity: 0.62; }
.signup__submit[disabled] { opacity: 0.45; cursor: progress; }

.signup__note {
  margin-top: 0.9rem;
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: var(--ivory-55);
}

.signup__status {
  margin-top: 0.9rem;
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  line-height: 1.5;
  min-height: 1.2em;
}

.signup__status:empty { margin-top: 0; min-height: 0; }
.signup__status[data-state="error"] { color: var(--butter); }

/* Success replaces the form entirely — a quiet confirmation rather than a
   banner stacked on top of a form the visitor is done with. */
.signup__done {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 30;
  font-size: var(--step-2);
  font-weight: 300;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.signup__done span {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--font-body);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  line-height: 1.5;
  opacity: 0.62;
}

/* Honeypot — off-screen, never announced, never tabbed to. */
.signup__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

/* On narrow screens the label and the field cannot share a line without the
   label running off the edge, so the control stacks and the button becomes a
   full-width tap target. */
@media (max-width: 30rem) {
  .signup__row {
    display: block;
    border-bottom: 0;
  }

  .signup__input {
    width: 100%;
    padding-right: 0;
    border-bottom: 1px solid var(--ivory-16);
    transition: border-color 240ms var(--ease);
  }

  .signup__input:focus { border-bottom-color: var(--butter); }

  .signup__submit {
    width: 100%;
    text-align: left;
    padding: 1.15rem 0 0.35rem;
  }
}

/* Light-background variant */
.signup--dark .signup__row { border-bottom-color: var(--espresso-14); }
.signup--dark .signup__row:focus-within { border-bottom-color: var(--oxblood); }
.signup--dark .signup__input::placeholder { color: var(--steel-ink); }
.signup--dark .signup__note,
.signup--dark .signup__status { color: var(--steel-ink); }
.signup--dark .signup__status[data-state="error"] { color: var(--oxblood); }


/* --------------------------------------------------------------------------
   6. About
   -------------------------------------------------------------------------- */

.about { background: var(--ivory); }

/* Centred, letter-spaced caps — the reference treatment. Kept to this one
   statement: it carries weight over a few lines and becomes hard work over
   many, so the descriptive copy further down stays in sentence case. */
.about__inner {
  display: grid;
  justify-items: center;
  gap: clamp(2rem, 4vw, 3rem);
  text-align: center;
}

.about__label { color: var(--steel-ink); }

.about__body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(0.95rem, 0.82rem + 0.62vw, 1.35rem);
  line-height: 1.85;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  max-width: 46ch;
  text-wrap: pretty;
}


/* --------------------------------------------------------------------------
   7. Disciplines — CURRENTLY UNUSED.

   This styled the "Das Training / The Practice" section (32°C heated vs
   unheated, with the four class names), which was removed from index.html.
   The rules are kept so the section can be restored by pasting the markup
   back; delete this block if it is not coming back.
   -------------------------------------------------------------------------- */

.practice { background: var(--stone); }

.practice__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--espresso-14);
}

.practice__label { color: var(--steel-ink); }

.practice__aside {
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  color: var(--steel-ink);
}

/* Two groups, split on the only distinction that matters: heated or not. */
.practice__groups {
  display: grid;
  gap: 0;
}

@media (min-width: 52rem) {
  .practice__groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.practice__group {
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

@media (min-width: 52rem) {
  .practice__group { padding-inline: clamp(1.5rem, 3vw, 3rem); }
  .practice__group:first-child { padding-left: 0; }
  .practice__group:last-child {
    padding-right: 0;
    border-left: 1px solid var(--espresso-14);
  }
}

.practice__state {
  color: var(--steel-ink);
  margin-top: 0.85rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.practice__list {
  display: grid;
  gap: 0;
}

.practice__item {
  padding-block: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid var(--espresso-14);
}

.practice__temp {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 72;
  font-weight: 200;
  font-size: var(--step-4);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--oxblood);
  margin: 0;
}

.practice__temp sup {
  font-size: 0.34em;
  vertical-align: super;
  letter-spacing: 0;
  margin-left: 0.06em;
}

/* Stands where the temperature would be, so the two columns share a baseline
   and the absence of heat is what the reader sees. */
.practice__temp--none { color: var(--stone-ink); }

.practice__name {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.practice__copy {
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--espresso-70);
  max-width: 34ch;
}


/* --------------------------------------------------------------------------
   7b. Why heat — the case for the heated room, kept deliberately quiet so the
       temperature above stays the loudest thing on the page.
   -------------------------------------------------------------------------- */

/* Stone rather than ivory: with the practice section gone, this sits directly
   under the ivory welcome block and needs to read as its own band. */
.benefits { background: var(--stone); }

.benefits__head {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}

@media (min-width: 52rem) {
  .benefits__head {
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4.5rem);
  }
}

.benefits__label { color: var(--steel-ink); }

.benefits__lede {
  font-size: var(--step-3);
  max-width: 22ch;
  text-wrap: balance;
}

.benefits__list {
  display: grid;
  gap: clamp(2rem, 3.5vw, 3rem) clamp(2rem, 4vw, 4rem);
}

@media (min-width: 40rem) {
  .benefits__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 68rem) {
  .benefits__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.benefits__item {
  border-top: 1px solid var(--espresso-14);
  padding-top: clamp(1.25rem, 2vw, 1.75rem);
}

.benefits__name {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  margin-bottom: 0.85rem;
}

.benefits__copy {
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--espresso-70);
  max-width: 36ch;
}


/* --------------------------------------------------------------------------
   8. Statement band
   -------------------------------------------------------------------------- */

/* The photograph carries the statement, the sign-up and the footer as one
   block. The image itself is fixed to the viewport and clipped to this
   container — so it is only ever asked to cover one screen rather than the
   full height of three sections, which keeps a 1254px source looking sharp. */
.closing {
  position: relative;
  isolation: isolate;
  background: var(--oxblood-deep);
  color: var(--ivory);
}

.closing__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  /* Turns this element into the containing block for the fixed image, which
     is what clips it to the section — and works on iOS, where
     background-attachment: fixed does not. */
  clip-path: inset(0);
}

.closing__media img {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
  object-position: 42% 50%;
}

.closing__media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Weighted to the left, where the copy sits, so the photograph stays
     visible across the right of the block without costing legibility. */
  background:
    linear-gradient(to bottom, rgba(42, 3, 11, 0.40) 0%, rgba(42, 3, 11, 0.50) 45%, rgba(42, 3, 11, 0.60) 78%, rgba(42, 3, 11, 0.86) 100%),
    linear-gradient(100deg, rgba(42, 3, 11, 0.66) 0%, rgba(42, 3, 11, 0.24) 52%, rgba(42, 3, 11, 0.04) 100%);
}

.closing > .section,
.closing > .footer {
  position: relative;
  z-index: 1;
  background: transparent;
}

.statement { color: var(--ivory); }

.statement__inner {
  position: relative;
  z-index: 1;
}

.statement__col { max-width: 46rem; }

.statement__label {
  color: var(--ivory-55);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.statement__quote {
  font-size: var(--step-4);
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  text-wrap: balance;
}

.statement__body {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ivory-70);
  max-width: 38ch;
}


/* --------------------------------------------------------------------------
   9. Join
   -------------------------------------------------------------------------- */

.join { color: var(--ivory); }

.join__inner {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: end;
}

@media (min-width: 56rem) {
  .join__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 26rem); }
}

.join__label {
  color: var(--ivory-55);
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.join__title {
  font-size: var(--step-4);
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
  text-wrap: balance;
}

.join__body {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ivory-70);
  max-width: 34ch;
}

.join .signup { max-width: none; }


/* --------------------------------------------------------------------------
   10. Footer
   -------------------------------------------------------------------------- */

.footer {
  color: var(--ivory);
  padding-bottom: clamp(2rem, 4vw, 3rem);
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--ivory-10);
}

.footer__mark {
  width: 1.6rem;
  flex: none;
  opacity: 0.75;
}

.footer__mark img { width: 100%; height: auto; }

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.25rem;
  align-items: center;
}

.footer__links a {
  color: var(--ivory-70);
  text-decoration: none;
  font-size: var(--step--1);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  transition: color 240ms var(--ease);
}

.footer__links a:hover { color: var(--ivory); }

.footer__place {
  font-size: var(--step--1);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--steel);
}


/* --------------------------------------------------------------------------
   11. Reduced motion
   -------------------------------------------------------------------------- */

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

  .hero__media img {
    animation: none;
    transform: scale(1.02);
  }

  .js [data-reveal],
  .js [data-reveal].is-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
