/* ==========================================================================
   scenes.css — the set pieces.

   Loaded after styles.css, which holds the design system. Split the way
   al-zaman-al-jameel splits its CSS: tokens and components in one file, the
   big staged moments in another, so a scene can be reworked without risking
   the system underneath it.

   Load order matters. Nothing here redefines a token; it only adds blocks.
   ========================================================================== */

/* ------------------------------------------------------- 1. image grading */

/* The venue photographs were shot under bright mall lighting, which is honest
   but flat. Grading them warm and down lets white text sit on top without a
   translucent plate — and a plate over a photo is the tell of a template. */
.grade img {
  filter: brightness(.74) contrast(1.12) saturate(1.08) sepia(.1);
}
.grade--deep img { filter: brightness(.48) contrast(1.2) saturate(1.05) sepia(.14); }

/* ------------------------------------------------------------ 2. marquee */

/* A slow band of the name and the brand star, used as a divider with a pulse.
   The track is forced to `direction: ltr` on purpose: this is the RTL trap
   that cost real debugging time on the previous project. Inside an RTL
   document a negative translateX moves content the opposite way to what you
   expect, and the band appears frozen. Pinning the track to LTR makes the
   sign unambiguous; the glyphs inside each item keep their own direction. */
.marquee {
  overflow: hidden;
  padding-block: var(--s-5);
  background: var(--brown-dark);
  border-block: 1px solid color-mix(in srgb, var(--sand) 14%, transparent);
  -webkit-mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track {
  direction: ltr;
  display: flex;
  align-items: center;
  gap: var(--s-6);
  width: max-content;
  animation: slide 42s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  display: flex; align-items: center; gap: var(--s-6);
  font-size: clamp(1.1rem, 2.4vw, 1.9rem);
  font-weight: 200; letter-spacing: .04em;
  color: color-mix(in srgb, var(--sand) 62%, transparent);
  white-space: nowrap;
}
.marquee__item::after {
  content: ""; flex: none; width: .6em; height: .6em;
  background: var(--brown-soft);
  -webkit-mask: url("../img/star.svg") center/contain no-repeat;
          mask: url("../img/star.svg") center/contain no-repeat;
}
/* The track holds the list twice, so -50% lands exactly on the seam. */
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* The full-viewport type moment that lived here (.shout) is gone. It set a
   written slogan over a flat brown panel with two faint stars; it has been
   replaced by .qband in cinematic.css, which sets a saying photographed on
   the venue's own wall over the photograph of that wall. */

/* ------------------------------------------------- 4. sticky scroll scene */

/* One image column that holds still while the text beside it scrolls, with
   the image swapping as each block takes the viewport. It is the cheapest way
   to make a short page feel directed rather than listed. */
.sticky-scene { position: relative; }
.sticky-scene__grid { display: grid; gap: var(--s-6); }

@media (min-width: 920px) {
  .sticky-scene__grid { grid-template-columns: 1fr 1fr; gap: var(--s-9); align-items: start; }
}

.sticky-scene__media {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--edge);
  overflow: hidden;
  background: var(--brown-dark);
}
@media (min-width: 920px) {
  .sticky-scene__media {
    position: sticky; inset-block-start: 14vh;
    height: 72vh; aspect-ratio: auto;
  }
}
.sticky-scene__media figure {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; transform: scale(1.04);
  transition: opacity .9s var(--ease), transform 1.4s var(--ease);
}
.sticky-scene__media figure.is-active { opacity: 1; transform: none; }
.sticky-scene__media img { width: 100%; height: 100%; object-fit: cover; }

.sticky-scene__steps > * { padding-block: var(--s-7); }
@media (min-width: 920px) {
  .sticky-scene__steps > * {
    min-height: 68vh;
    display: flex; flex-direction: column; justify-content: center;
  }
}
.sticky-scene__steps h3 { font-size: var(--t-h2); margin-block-end: var(--s-4); }
.step__n {
  font-size: var(--t-small); letter-spacing: .24em;
  color: var(--brown-soft); margin-block-end: var(--s-3);
}

/* .dish and .strip are gone too. The food cards are now .plate and the
   interior row is now .rail, both in cinematic.css — .dish depended on a
   :hover zoom that a phone can never trigger, and .rail replaces .strip with
   edge-to-edge bleed and snap behaviour. */

/* ------------------------------------------------------ 7. detail inset */

/* A small framed photo that overlaps the panel edge — the trick that keeps a
   two-column block from reading as two rectangles. */
.inset {
  position: relative;
  border-radius: var(--edge);
  overflow: hidden;
  box-shadow: 0 30px 70px -34px rgb(26 17 7 / .75);
}
@media (min-width: 920px) {
  .inset--lift { margin-block-start: calc(var(--s-9) * -1); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .sticky-scene__media figure { transition: none; }
}

/* ======================================================= 8. intro curtain */

/* The wordmark is a delicate monoline lockup. Measured at small sizes it
   collapses: at 150px the strokes go muddy and the hairline Latin row stops
   being legible, which is what the client was seeing. The fix is not a
   sharper filter — it is to stop using the full lockup small, and to give it
   one moment at a size where it is actually beautiful.

   So the page opens on a curtain: the logo alone on the darkest brand brown,
   large, over the house's own sadu cloth. Then the curtain lifts and the
   photography takes over. The hero no longer carries a wordmark at all.

   `display: none` is the default on purpose — JavaScript opts in. A visitor
   without JS must never be left staring at a curtain that cannot lift. */
.intro { display: none; }

.intro.is-playing {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--brown-dark);
  transition: transform 1.1s cubic-bezier(.76, 0, .24, 1),
              opacity .9s ease;
}
/* The curtain is the first thing anyone sees, so it carries the house's own
   cloth. It used to carry lattice.svg — a tiling star field authored to match
   a panel in the profile PDF, i.e. invented. That file is gone from the
   project entirely; this was its last use. Held at .14 so it is a texture
   behind the mark, not a backdrop competing with it. */
.intro.is-playing::before {
  content: "";
  position: absolute; inset: 0;
  background: url("../../media/photos/sadu-textile.jpeg") 50% 50% / cover;
  opacity: .14;
}
.intro__inner { position: relative; text-align: center; }

.intro__logo {
  width: min(74vw, 460px);          /* comfortably above the collapse point */
  /* Explicit even though the base `img` rule now carries it, because this is
     the rule that sets a width with no height and this is where the bug was:
     the height="355" attribute stayed in force and crushed a 3.38 wordmark
     into 0.81. Anyone editing the width here should see the pairing. */
  height: auto;
  margin-inline: auto;
  opacity: 0;
  transform: translateY(14px) scale(.97);
  animation: introMark 1.5s var(--ease) forwards;
}
@keyframes introMark {
  to { opacity: 1; transform: none; }
}

/* A hairline that draws itself under the mark — the only motion that reads as
   "being poured" without animating a literal cup. */
.intro__rule {
  display: block;
  height: 1px;
  width: min(74vw, 460px);
  margin: var(--s-6) auto 0;
  background: var(--brown-soft);
  transform: scaleX(0);
  transform-origin: center;
  animation: introRule 1.5s .5s var(--ease) forwards;
}
@keyframes introRule { to { transform: scaleX(1); } }

.intro__tag {
  margin-block-start: var(--s-5);
  font-size: var(--t-small);
  letter-spacing: .34em;
  color: color-mix(in srgb, var(--sand) 52%, transparent);
  opacity: 0;
  animation: introMark 1.2s .9s var(--ease) forwards;
}

.intro.is-leaving { transform: translateY(-101%); }

/* While the curtain is up the page must not scroll behind it. */
.is-intro-locked { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  /* No curtain at all: an entrance animation is exactly what this setting
     asks us to skip, and the content behind it is the point. */
  .intro.is-playing { display: none; }
}

/* ------------------------------------------------------- 9. small helpers */

/* These exist as classes rather than inline style attributes because the CSP
   sets `style-src` without 'unsafe-inline' — an inline style attribute is
   silently dropped by the browser, which is a very quiet way to ship a
   broken layout. */
.eyebrow--light { color: var(--sand-dark); }
.foot__top { margin-block-end: var(--s-8); }
