/* MessMate opening stage (Claude, 4 Nov 2026).

   The first screen of the home page: a full-height dark field with the set built in 3D on top of it, an oversized
   wordmark, one line of copy, and the real colourways to pick from under the scene. It is the only dark surface
   on the site, which is the point - the cream page underneath reads as a release when you scroll past it.

   Kept in its own file because it is the part of the site most likely to be re-cut.

   Height: the header and the announcement bar sit above this section in normal flow, so a plain 100svh would push
   the buttons off the first screen. --bar-h is already a token; 44px covers the announcement strip.

   Wide screens: the set sits top right and the wordmark bottom left, both absolutely placed over one field. A
   full-width gradient drags the product down with the type, so the scrim is an ellipse anchored to the bottom left
   corner that dies out well before the product.

   PHONES: nothing is laid over the product. The section becomes a plain column - the 3D scene, then its colour
   picker, then the words - so the type can never cover the set. An earlier cut kept the scene absolutely placed
   over the top half and let the copy grow up into it; with the wordmark, a four-line paragraph and two buttons the
   copy was taller than the space left for it, and the two printed on top of each other. The picker hangs from the
   bottom edge of the scene (top: 100%) rather than sitting inside the picture, and the scene reserves room for it
   with a bottom margin. It stays a CHILD of the scene element because the engine looks for its swatches inside the
   scene it is drawing.

   Stacking on wide screens: the scene sits ABOVE the scrim (z-index 3 against the scrim's 2) for the same reason -
   the picker lives inside the scene, and under the scrim it would be dimmed.

   The copy's entrance is pure CSS on page load and owes nothing to the 3D: WebGL may be slow, refused or absent, and
   the words still have to arrive properly. The 3D build runs to its own clock in assets/mm3d.js and the two are
   timed to overlap rather than to wait on each other.

   The easing token is --mm-ease; there is no --ease (an earlier cut of this file referred to one, which silently
   cancelled the two transitions that used it). */

.mm-stage {
  position: relative; isolation: isolate; overflow: clip;
  min-height: 76vh;
  min-height: min(calc(100svh - var(--bar-h) - 44px), 920px);
  display: grid; grid-template-rows: 1fr auto;
  color: #fff;
  background: radial-gradient(118% 86% at 64% 34%, #3c4f1e 0%, #273413 42%, #161e0b 74%, #101607 100%);
}
.mm-stage__scene { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; }
.mm-stage__scene canvas { display: block; width: 100%; height: 100%; cursor: grab; }
.mm-stage__scene canvas:active { cursor: grabbing; }

/* a soft pool of light behind the set, so it sits in the field rather than on it */
.mm-stage__glow {
  position: absolute; left: 50%; top: 42%; z-index: 0; pointer-events: none;
  width: min(1180px, 104vw); aspect-ratio: 1.5; transform: translate(-50%, -50%);
  background: radial-gradient(50% 50% at 50% 50%, color-mix(in srgb, var(--mm-pine-tint) 34%, transparent) 0%, transparent 68%);
  filter: blur(14px);
}
.mm-stage::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(to top, rgba(10, 14, 6, .9) 0%, rgba(10, 14, 6, .52) 24%, rgba(10, 14, 6, .08) 52%, transparent 70%);
}
/* the still that shows instead of the scene when WebGL is missing */
.mm-stage__fallback {
  position: absolute; left: 50%; top: 42%; z-index: 1; transform: translate(-50%, -50%);
  width: min(520px, 70vw); height: auto; opacity: 0; transition: opacity .6s var(--mm-ease);
}
.mm-no3d .mm-stage__fallback { opacity: .95; }

/* ---------- pick a colourway ----------
   These buttons are children of the scene element on purpose: the engine reads the swatches inside its own host.
   They fade in with the scene so nothing flashes before the set has built itself. */
.mm-stage__pick {
  position: absolute; left: 50%; bottom: 10px; z-index: 2; transform: translateX(-50%);
  display: grid; justify-items: center; gap: 8px;
  width: max-content; max-width: calc(100% - 24px);
  opacity: 0; transition: opacity .8s var(--mm-ease) .8s;
  touch-action: manipulation;
}
.mm-stage__scene.is-ready .mm-stage__pick { opacity: 1; }
.mm-no3d .mm-stage__pick { display: none; }
.mm-stage__pickl {
  margin: 0; font: 600 10px/1 var(--mm-sans); letter-spacing: .22em; text-transform: uppercase;
  color: rgba(255, 255, 255, .6); text-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}
.mm-stage__sw {
  display: flex; gap: 9px; padding: 8px; max-width: 100%; border-radius: 999px;
  background: rgba(10, 14, 6, .5); border: 1px solid rgba(255, 255, 255, .17);
  -webkit-backdrop-filter: blur(9px); backdrop-filter: blur(9px);
  overflow-x: auto; scrollbar-width: none;
}
.mm-stage__sw::-webkit-scrollbar { display: none; }
.mm-swatch--lg { width: 34px; height: 34px; border-color: rgba(255, 255, 255, .88); }
.mm-swatch--lg[aria-pressed="true"] { box-shadow: 0 0 0 2px #fff, 0 6px 14px rgba(0, 0, 0, .45); }
.mm-stage__cap {
  margin: 0; font: 500 12.5px/1.3 var(--mm-sans); text-align: center;
  color: rgba(255, 255, 255, .86); text-shadow: 0 2px 10px rgba(0, 0, 0, .65);
}

.mm-stage__copy {
  position: relative; z-index: 4; grid-row: 2;
  width: 100%; max-width: var(--mm-wrap); margin: 0 auto;
  padding: 0 var(--mm-pad) clamp(46px, 7vh, 86px);
}
.mm-stage__eyebrow {
  margin: 0 0 16px; font: 600 11px/1 var(--mm-sans); letter-spacing: .24em; text-transform: uppercase;
  color: color-mix(in srgb, var(--mm-pine-tint) 86%, #fff);
  text-shadow: 0 2px 14px rgba(0, 0, 0, .6);
}
.mm-stage__word {
  margin: 0; font-family: var(--mm-display); font-weight: 500; font-style: normal;
  font-size: clamp(50px, 10vw, 152px); line-height: .88; letter-spacing: -.035em; color: #fff;
  text-shadow: 0 10px 40px rgba(0, 0, 0, .8), 0 2px 10px rgba(0, 0, 0, .5);
}
.mm-stage__lede {
  margin: 18px 0 0; max-width: 32ch; font-size: clamp(15px, 1.3vw, 18.5px); line-height: 1.58;
  color: rgba(255, 255, 255, .88); text-shadow: 0 2px 16px rgba(0, 0, 0, .7);
}
.mm-stage__ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
.mm-stage .mm-btn--light { background: #fff; color: var(--mm-ink); border-color: #fff; }
.mm-stage .mm-btn--light:hover { background: var(--mm-pine-tint); border-color: var(--mm-pine-tint); }
.mm-stage .mm-btn--ghost { border-color: rgba(255, 255, 255, .5); color: #fff; background: rgba(10, 14, 6, .34); }
.mm-stage .mm-btn--ghost:hover { border-color: #fff; background: rgba(255, 255, 255, .14); }

/* the product and price of what is on screen, so the opening sells rather than only looking good */
.mm-stage__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 20px 0 0;
  font-size: 13.5px; color: rgba(255, 255, 255, .72);
}
.mm-stage__meta a { color: #fff; font-weight: 600; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .42); padding-bottom: 2px; }
.mm-stage__meta a:hover { border-bottom-color: #fff; }
.mm-stage__meta span { position: relative; padding-left: 17px; }
.mm-stage__meta span::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 9px; height: 9px; margin-top: -4px;
  border-radius: 50%; background: var(--mm-pine-tint); opacity: .8;
}

/* ---------- the copy's entrance ----------
   Staggered from the top down, so the eye lands on the wordmark and then follows the line of reading. It starts at
   once: the stage is the first thing on the page and there is nothing above it to wait for. */
@media (prefers-reduced-motion: no-preference) {
  .mm-stage__eyebrow, .mm-stage__word, .mm-stage__lede, .mm-stage__ctas, .mm-stage__meta {
    animation: mmStageIn .9s cubic-bezier(.16, .84, .3, 1) both;
  }
  .mm-stage__eyebrow { animation-delay: .10s; }
  .mm-stage__word    { animation-delay: .20s; animation-duration: 1.1s; }
  .mm-stage__lede    { animation-delay: .42s; }
  .mm-stage__ctas    { animation-delay: .56s; }
  .mm-stage__meta    { animation-delay: .68s; }
}
@keyframes mmStageIn {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* the scroll cue: a line that fills from the top, then empties from the top again */
.mm-stage__scroll {
  position: absolute; left: 50%; bottom: 16px; z-index: 5; transform: translateX(-50%);
  display: grid; justify-items: center; gap: 10px; text-decoration: none;
  font: 600 10px/1 var(--mm-sans); letter-spacing: .26em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
}
.mm-stage__scroll:hover { color: #fff; }
.mm-stage__scroll i { display: block; width: 1px; height: 40px; background: rgba(255, 255, 255, .7); transform-origin: top; }
@media (prefers-reduced-motion: no-preference) {
  .mm-stage__scroll i { animation: mmStageCue 2.4s cubic-bezier(.7, 0, .3, 1) infinite; }
}
@keyframes mmStageCue {
  0%   { transform: scaleY(0); transform-origin: top }
  45%  { transform: scaleY(1); transform-origin: top }
  55%  { transform: scaleY(1); transform-origin: bottom }
  100% { transform: scaleY(0); transform-origin: bottom }
}
.mm-stage__drag {
  position: absolute; right: var(--mm-pad); bottom: 22px; z-index: 5;
  display: inline-flex; align-items: center; gap: 8px; pointer-events: none;
  font: 500 12px/1 var(--mm-sans); color: rgba(255, 255, 255, .5); opacity: 0;
  transition: opacity .7s var(--mm-ease) .9s;
}
.mm-stage__scene.is-ready ~ .mm-stage__drag { opacity: 1; }
.mm-stage__drag .mm-ic { width: 15px; height: 15px; }

/* Controls are controls: someone who has asked for less motion should not wait out a fade before the colour
   picker is there. They appear with the scene instead. */
@media (prefers-reduced-motion: reduce) {
  .mm-stage__pick, .mm-stage__drag, .mm-stage__fallback { transition: none; }
}

@media (min-width: 861px) {
  /* the set lives in the top right; the words own the bottom left */
  .mm-stage__scene { left: auto; right: -1%; width: 68%; height: 94%; top: -3%; }
  .mm-stage__glow { left: 64%; top: 40%; width: min(920px, 72vw); }
  /* an ellipse in the bottom left corner only - the product is never touched */
  .mm-stage::after {
    background: radial-gradient(58% 74% at 0% 100%,
      rgba(10, 14, 6, .94) 0%, rgba(10, 14, 6, .66) 34%, rgba(10, 14, 6, .22) 60%, transparent 80%);
  }
}

/* ---------- phones and small tablets: a column, nothing on top of anything ---------- */
@media (max-width: 860px) {
  .mm-stage { display: flex; flex-direction: column; min-height: 0; }
  /* the picture: in the flow, at the proportions the engine's narrow framing was tuned for (taller than wide) */
  .mm-stage__scene {
    position: relative; inset: auto; flex: none; width: 100%;
    height: min(122vw, 62svh, 640px); min-height: 330px;
    margin-bottom: 122px;                 /* room for the colour picker that hangs below it */
  }
  .mm-stage__glow { left: 50%; top: 24%; width: min(680px, 118vw); }
  .mm-stage__fallback { position: absolute; top: 24%; }
  .mm-stage::after { background: linear-gradient(to top, rgba(10, 14, 6, .6) 0%, rgba(10, 14, 6, .2) 30%, transparent 48%); }

  /* the picker: its own band under the picture, bigger targets, one clean line of caption */
  .mm-stage__pick { bottom: auto; top: 100%; margin-top: 4px; gap: 9px; }
  .mm-stage__pickl { font-size: 10px; letter-spacing: .2em; }
  .mm-stage__sw { gap: 10px; padding: 7px 9px; }
  .mm-swatch--lg { width: 38px; height: 38px; }
  .mm-stage__cap { font-size: 13px; }

  .mm-stage__copy { flex: none; text-align: center; padding-bottom: clamp(40px, 6vh, 64px); }
  .mm-stage__lede { margin-inline: auto; max-width: 34ch; }
  .mm-stage__ctas { justify-content: center; }
  .mm-stage__ctas .mm-btn { flex: 1 1 210px; justify-content: center; max-width: 320px; }
  .mm-stage__meta { justify-content: center; margin-top: 16px; }
  /* on a phone the page obviously scrolls, and the cue only crowds the buttons */
  .mm-stage__scroll, .mm-stage__drag { display: none; }
}
