/* ============================================================================
   MOOD by Ibramo
   A material is a feeling. This stylesheet is the room it lives in.
   ---------------------------------------------------------------------------
   1. Tokens          2. Reset & type      3. Atmosphere
   4. The object      5. The first view    6. Becoming
   7. The shop        8. The way out       9. Chrome (nav / cursor / veil)
  10. Responsive     11. Reduced motion
   ========================================================================== */

/* ── 1. TOKENS ───────────────────────────────────────────────────────────── */
:root{
  /* runtime colour — written by mood.js as "r g b" triplets */
  --bg: 239 233 225;
  --fg: 26 23 20;
  --light-c: 255 248 236;
  --light-a: .42;
  --vig: .10;

  /* runtime scalars */
  --u: 1;          /* scene-length unit                      */
  --vel: 0;        /* smoothed scroll velocity, px           */
  --mx: 0;         /* pointer offset from centre, -1 … 1     */
  --my: 0;
  --nav-o: 1;      /* the header is present from the first view */

  --serif: "Cormorant Garamond", Cormorant, Georgia, "Times New Roman", serif;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  --edge: 5.6vw;   /* the page's quiet margin */
}

/* ── 2. RESET & BASE TYPE ────────────────────────────────────────────────── */
*, *::before, *::after{ box-sizing: border-box; }
html{ -webkit-text-size-adjust: 100%; }
body{
  margin: 0;
  background: rgb(var(--bg));
  color: rgb(var(--fg));
  font-family: var(--sans);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color .12s linear;
}
img, svg, picture{ display: block; max-width: 100%; }
h1, h2, h3, p, figure, figcaption{ margin: 0; }
a{ color: inherit; text-decoration: none; }
button{ font: inherit; color: inherit; background: none; border: 0; padding: 0; }

::selection{ background: rgb(var(--fg) / .12); }

:focus-visible{
  outline: 1px solid rgb(var(--fg) / .55);
  outline-offset: 6px;
}

/* :where() so this carries no weight: Tailwind ships the same rule and its
   `sm:not-sr-only` has to be able to undo it inside the shop section. */
:where(.sr-only){
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

main{ position: relative; z-index: 1; }

.scene{ position: relative; }
.stage{
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
}

/* elements the engine drives start invisible so nothing flashes on load */
[data-a]{ opacity: 0; }

/* the mask-reveal wrapper: text rises out of a fixed window */
.rv{ display: block; overflow: hidden; padding-block: .06em; }
.rv-i{ display: block; will-change: transform, opacity; }


/* ── 3. ATMOSPHERE ───────────────────────────────────────────────────────── */
#atmos{
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none; overflow: hidden;
}

/* the opening: sunrise over a sea of clouds — a still, painted soft (see
   img/sky-*.webp), so it needs no runtime blur. The sun sits just under the
   mark; the cloud shadows below carry the hero line. */
.at-sea{
  position: absolute; inset: 0;
  opacity: 0;
  visibility: hidden;
}
.at-sea.is-live{ visibility: visible; }
.at-sea img{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 58%;          /* keep the sun near the horizon line on any crop */
}
/* the live clouds (sky.js) fade in over the still once their first frame is drawn */
.at-sky{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  transition: opacity 1.4s ease;
}
.at-sea.sky-live .at-sky{ opacity: 1; }
.at-sea-scrim{
  position: absolute; inset: 0;
  background: linear-gradient(rgb(6 10 14 / .22), transparent 30%, transparent 62%, rgb(4 7 10 / .38));
}

.at-light{
  position: absolute; inset: -25%;
  background: radial-gradient(52% 44% at 50% 30%,
              rgb(var(--light-c) / var(--light-a)), transparent 72%);
  will-change: transform;
}

.at-tex{
  position: absolute; inset: -8%;
  background-size: cover; background-position: center;
  opacity: 0;
  mix-blend-mode: soft-light;
  filter: contrast(.86) brightness(1.04);
}
.at-tex[data-tex="steel"]{  background-image: url(../img/tex-steel.webp); mix-blend-mode: screen; }

/* ── 4. THE OBJECT ───────────────────────────────────────────────────────── */
.obj{
  position: absolute; inset: 0; margin: auto;
  width: min(58vw, 660px);
  height: calc(min(58vw, 660px) * .64);
  isolation: isolate;
  will-change: transform;
  z-index: 3;
}

.mat{
  position: absolute; inset: 0;
  will-change: transform, opacity, filter;
}
.mat picture{ display: contents; }
.mat img{
  width: 100%; height: 100%;
  object-fit: contain;
  user-select: none; -webkit-user-drag: none;
}

/* the sheen silhouettes are url-referenced masks: no webp, or no masking at
   all, means no sheen rather than a bare gradient across the object */
html.no-webp .sheen,
html.no-mask .sheen{ display: none; }

/* light travelling over the surface — clipped to the object's own silhouette */
.sheen{
  position: absolute; inset: 0;
  opacity: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: 250% 100%;
  -webkit-mask-size: contain;   mask-size: contain;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.sheen--steel{
  -webkit-mask-image: url(../img/logo-steel.webp); mask-image: url(../img/logo-steel.webp);
  background-image: linear-gradient(108deg, transparent 26%,
      rgb(120 140 170 / .30) 38%, rgb(255 255 255 / .82) 47%,
      rgb(210 226 246 / .40) 53%, rgb(40 48 60 / .30) 62%, transparent 74%);
  mix-blend-mode: screen;
  animation: sweep 15s linear infinite;
}
@keyframes sweep{
  from{ background-position: -70% 50%; }
  to  { background-position: 175% 50%; }
}

/* the object sits in its own pool of light */
.halo{
  position: absolute; inset: -14% -10%;
  background: radial-gradient(50% 46% at 50% 52%, rgb(234 242 252 / .26), transparent 72%);
  opacity: 0; z-index: -1;
  filter: blur(8px);
}
/* ── 5. THE FIRST VIEW ───────────────────────────────────────────────────── */
#opening{ height: calc(240 * var(--u) * 1vh); }

/* hero */
.hero-copy{
  position: absolute; left: 0; right: 0; bottom: 19vh;
  display: grid; place-items: center;
  z-index: 5;
}
.hero-line{
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.62vw, 1.55rem);
  font-style: italic;
  font-weight: 300;
  letter-spacing: .05em; text-indent: .05em;   /* the trailing track, put back */
  line-height: 1.55;
  text-align: center;
  color: rgb(var(--fg) / .86);
  /* the clouds drift behind it, so it carries its own soft shade */
  text-shadow: 0 1px 14px rgb(6 9 14 / .55), 0 0 2px rgb(6 9 14 / .35);
  position: relative;
}
.hero-line::before{
  content: ""; position: absolute; inset: -60% -18%; z-index: -1;
  background: radial-gradient(closest-side, rgb(6 9 14 / .34), transparent);
  pointer-events: none;
}

.corner{
  position: absolute; bottom: 2.6rem;
  font-size: .62rem; font-weight: 400;
  letter-spacing: .30em; text-transform: uppercase;
  color: rgb(var(--fg) / .40);
  z-index: 5;
}
.corner--l{ left: var(--edge); }
.corner--r{
  right: var(--edge);
  display: flex; align-items: center; gap: 1rem;
}
.cue em{ font-style: normal; }
.cue-line{
  position: relative; display: block;
  width: 1px; height: 62px;
  background: rgb(var(--fg) / .16);
  overflow: hidden;
}
.cue-line b{
  position: absolute; inset-inline: 0; top: 0;
  height: 26px;
  background: linear-gradient(rgb(var(--fg) / 0), rgb(var(--fg) / .85));
  animation: cue 3.8s cubic-bezier(.6,0,.35,1) infinite;
}
@keyframes cue{
  0%   { transform: translateY(-100%); opacity: 0 }
  22%  { opacity: 1 }
  78%  { opacity: 1 }
  100% { transform: translateY(240%); opacity: 0 }
}

/* ── 6. BECOMING ─────────────────────────────────────────────────────────── */
/* It starts one screen early, so its stage pins at the exact moment the first
   view's progress reaches its end: the mark goes and the first word is already
   standing in its place. The first view's stage then scrolls out behind it,
   empty. */
#becoming{
  height: calc(340 * var(--u) * 1vh);
  margin-top: -100vh; margin-top: -100svh;
}
.stage--words{ display: grid; place-items: center; }
/* The words only fade and rise a little, in either direction of scroll. They
   never change their tracking or their shape, so a word is always whole —
   scrolling back up shows it exactly as it was on the way down. */
.stage--words .rv{ overflow: visible; }
/* Each word is one unbroken line, so its size is decided by how many letters
   it has: --n comes from the markup, and the width it would need is never
   allowed past 86% of the screen. Pure arithmetic, no measuring, so it holds
   on any screen, in either language, and before the webfont has landed. The
   .82 is one character's advance in em, wide enough to cover the fallback
   face that draws while the real one loads. */
.word{
  grid-area: 1 / 1;
  --n: 7;
  --fits: calc(86vw / (var(--n) * .82));
  font-family: var(--serif);
  font-weight: 300;
  font-size: min(clamp(3.2rem, 12vw, 11.5rem), var(--fits));
  line-height: 1;
  letter-spacing: .055em; text-indent: .055em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgb(var(--fg) / .92);
}
.word--mood{ letter-spacing: .18em; text-indent: .18em; --fits: calc(86vw / (var(--n) * .98)); }
.word-note{
  position: absolute; left: 0; right: 0; bottom: 16vh;
  text-align: center;
  font-size: .64rem; letter-spacing: .34em; text-indent: .34em; text-transform: uppercase;
  color: rgb(var(--fg) / .40);
}


/* ── 7. THE SHOP ─────────────────────────────────────────────────────────── */
/* The explorer is the last section. It was written to own the viewport, so
   here it owns one screen of the page instead: everything it fixes to the
   window is fixed to this stage. */
#shop{
  position: relative; z-index: 1;
  height: 100vh; height: 100svh;
  overflow: hidden;
  background: #f4f2ed;
}
#shop .fixed{ position: absolute; }
/* The table claims every touch for its own panning, which would make the shop
   a dead end on a phone. It gets the same deal as the wheel: before the
   section has the screen every swipe belongs to the page, and once it is
   pinned the table keeps the swipes that go further in, while a swipe
   downward — the one that goes back up the page — is still the page's. */
#shop:not(.is-pinned) .pt-stage{ touch-action: pan-y; }
#shop.is-pinned .pt-stage{ touch-action: pan-down; }
/* and nothing inside it scrolls until it has the screen — on a touch screen
   a swipe over the collections list would otherwise stop the page halfway */
#shop:not(.is-pinned) .quiet-scroll{ overflow: hidden; }
#shop-root{ position: absolute; inset: 0; }

.shop-fallback{
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 1rem;
  padding: 0 var(--edge);
  max-width: 46ch; margin: 0 auto;
  text-align: center;
  color: rgb(26 23 20 / .7);
}


/* ── 8. THE WAY OUT ──────────────────────────────────────────────────────── */
.enter{
  position: relative;
  margin-top: 5rem;
  display: inline-flex; flex-direction: column; align-items: center; gap: .95rem;
  font-size: .68rem; letter-spacing: .36em; text-indent: .36em; text-transform: uppercase;
  color: rgb(var(--fg) / .82);
}
.enter i{
  display: block; height: 1px; width: 100%;
  background: rgb(var(--fg) / .28);
  transform: scaleX(.34); transform-origin: 50% 50%;
  transition: transform 1.1s cubic-bezier(.16,1,.3,1), background-color .8s;
}
.enter:hover i, .enter:focus-visible i{ transform: scaleX(1); background: rgb(var(--fg) / .6); }

#foot{
  position: relative; z-index: 1;
  display: flex; justify-content: space-between; gap: 2rem;
  padding: 0 var(--edge) 3.2rem;
  font-size: .6rem; letter-spacing: .28em; text-transform: uppercase;
  color: rgb(var(--fg) / .34);
}


/* ── 9. CHROME ──────────────────────────────────────────────────────────── */
#nav{
  position: fixed; inset: 0 0 auto; z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  gap: 2rem;
  padding: 1.6rem var(--edge);
  pointer-events: none;
}
#nav > *{ pointer-events: auto; }

.nav-mark span{
  display: block;
  opacity: calc(.28 + .72 * var(--nav-o));
  transition: opacity .8s;
  font-family: var(--serif); font-size: 1.05rem; font-weight: 400;
  letter-spacing: .42em; text-transform: uppercase;
  line-height: 1;
}
.nav-mark em{
  display: block; margin-top: .42rem;
  font-style: normal; font-size: .52rem;
  letter-spacing: .26em; text-transform: uppercase;
  color: rgb(var(--fg) / .40);
  opacity: var(--nav-o);
  transition: opacity .8s;
}

.nav-caps{
  display: flex; align-items: center; gap: 1.75rem;
  padding: .62rem 1.5rem;
  border-radius: 999px;
  font-size: .62rem; letter-spacing: .26em; text-transform: uppercase;
  color: rgb(var(--fg) / .62);
  background: linear-gradient(150deg, rgb(255 255 255 / .17), rgb(255 255 255 / .04) 58%, rgb(255 255 255 / .11));
  border: 1px solid rgb(255 255 255 / .18);
  -webkit-backdrop-filter: blur(17px) saturate(1.3) brightness(1.04);
          backdrop-filter: blur(17px) saturate(1.3) brightness(1.04);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .42),
    inset -1px -1px 0 rgb(var(--fg) / .04),
    0 16px 36px -28px rgb(0 0 0 / .5);
  opacity: var(--nav-o);
  transition: opacity 1s;
}
.nav-caps a{ transition: color .5s; }
.nav-caps a:hover{ color: rgb(var(--fg)); }
/* the studio, until it has a page of its own to point at */
.nav-soon{ color: rgb(var(--fg) / .62); }
.nav-soon .nv-short{ display: none; }
.nav-lang{ letter-spacing: .14em; }

/* the glass lens cursor — it follows the pointer and holds its size; it no
   longer swells or names what is under it when that is a link */
#cursor{
  position: fixed; top: 0; left: 0; z-index: 90;
  pointer-events: none;
  transform: translate3d(-200px, -200px, 0);
  will-change: transform;
  opacity: 0;
  transition: opacity .5s;
}
body.has-lens #cursor{ opacity: 1; }
.cur-lens{
  position: absolute; left: -46px; top: -46px;
  width: 92px; height: 92px;
  border-radius: 50%;
  -webkit-backdrop-filter: blur(4px) saturate(1.35) brightness(1.03);
          backdrop-filter: blur(4px) saturate(1.35) brightness(1.03);
  border: 1px solid rgb(var(--fg) / .18);
  box-shadow:
    inset 0 1px 2px rgb(255 255 255 / .5),
    inset 0 -3px 8px rgb(var(--fg) / .08),
    0 10px 26px -14px rgb(0 0 0 / .5);
  transform: scale(.28);
  transition: border-color .5s;
}
.cur-dot{
  position: absolute; left: -1.5px; top: -1.5px;
  width: 3px; height: 3px; border-radius: 50%;
  background: rgb(var(--fg) / .7);
}

/* entry veil */
#veil{
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  background: rgb(var(--bg));
  transition: opacity 1.4s cubic-bezier(.4,0,.2,1), visibility 0s linear 1.4s;
}
body.is-ready #veil{ opacity: 0; visibility: hidden; }
.veil-mark{ display: grid; justify-items: center; gap: 1.15rem; }
.veil-word{
  font-family: var(--serif); font-weight: 300;
  font-size: 1.35rem; letter-spacing: .55em; text-transform: uppercase;
  text-indent: .55em;
  color: rgb(var(--fg) / .8);
}
.veil-rule{ display: block; width: 120px; height: 1px; background: rgb(var(--fg) / .12); overflow: hidden; }
.veil-rule i{
  display: block; height: 100%; width: 100%;
  background: rgb(var(--fg) / .55);
  transform-origin: 0 50%;
  animation: veilrule 2.6s cubic-bezier(.5,0,.2,1) infinite;
}
@keyframes veilrule{
  0%  { transform: scaleX(0); transform-origin: 0 50% }
  48% { transform: scaleX(1); transform-origin: 0 50% }
  52% { transform: scaleX(1); transform-origin: 100% 50% }
  100%{ transform: scaleX(0); transform-origin: 100% 50% }
}
.veil-sub{
  font-size: .55rem; letter-spacing: .34em; text-transform: uppercase;
  color: rgb(var(--fg) / .34);
}


/* ── 10. RESPONSIVE ──────────────────────────────────────────────────────── */
@media (max-width: 1100px){
  :root{ --edge: 6.5vw; }
}

@media (max-width: 820px){
  /* the story is re-staged for a vertical screen, not merely shrunk */
  :root{ --u: .72; --edge: 7vw; }

  .obj{ width: 88vw; height: calc(88vw * .64); }

  .hero-copy{ bottom: 24vh; }
  .hero-line{ font-size: 1.02rem; }
  .corner{ bottom: 2rem; font-size: .55rem; letter-spacing: .24em; }
  .corner--l{ max-width: 40vw; }
  .cue-line{ height: 42px; }

  .word{ font-size: min(15vw, var(--fits)); }
  .word--mood{ letter-spacing: .14em; text-indent: .14em; }

  #nav{ padding: 1.15rem var(--edge); gap: 1rem; }
  .nav-mark span{ font-size: .88rem; letter-spacing: .34em; }
  /* the capsule holds the only way to the bag, so it never leaves — it just
     tightens, and the studio steps out on the narrowest screens */
  .nav-caps{ gap: 1rem; padding: .5rem 1rem; font-size: .55rem; letter-spacing: .18em; }

  .enter{ margin-top: 3.5rem; letter-spacing: .28em; text-indent: .28em; }
  #foot{ flex-direction: column; gap: .7rem; text-align: center; align-items: center; }
}

/* the capsule has to hold four things beside the wordmark: below this the
   studio goes by its short name rather than leaving the header */
@media (max-width: 560px){
  .nav-soon .nv-long{ display: none; }
  .nav-soon .nv-short{ display: inline; }
  .nav-caps{ gap: .8rem; padding: .45rem .85rem; letter-spacing: .14em; }
  .nav-mark span{ font-size: .78rem; letter-spacing: .26em; }
  .nav-mark em{ font-size: .46rem; letter-spacing: .18em; }
}

@media (max-width: 420px){
  .word{ font-size: min(17vw, var(--fits)); }
  :root{ --edge: 5vw; }
  .nav-caps{ gap: .68rem; padding: .42rem .7rem; font-size: .52rem; }
}

/* pointer-coarse devices never get the lens */
@media (pointer: fine){
  body.has-lens, body.has-lens *{ cursor: none; }
}


/* ── 11. REDUCED MOTION ──────────────────────────────────────────────────── */
/* Motion is toned down, but never so far that a state flashes past unread. */
@media (prefers-reduced-motion: reduce){
  :root{ --u: .85; }
  .sheen{ animation: none; background-position: 50% 50%; }
  .cue-line b{ animation: none; opacity: .6; transform: translateY(40%); }
  .veil-rule i{ animation: none; }
  .rv{ overflow: visible; }
  .enter i{ transition-duration: .2s; }
  #cursor{ display: none; }
  body.has-lens, body.has-lens *{ cursor: auto; }
}
