/* ==========================================================================
   Samsara Objects — one-page scrolling site
   ========================================================================== */

@font-face {
  font-family: "ABC Monument Grotesk";
  src: url("../fonts/ABCMonumentGrotesk-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "ABC Monument Grotesk Mono";
  src: url("../fonts/ABCMonumentGroteskMono-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Kohinoor Arabic";
  src: url("../fonts/KohinoorArabic-Demi.otf") format("opentype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --grey: #e9e4d9;
  --pink: #dcb7ab;
  --yellow: #ffef00;
  --ink: #231f20;

  --font-body: "ABC Monument Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "ABC Monument Grotesk Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --font-fa: "Kohinoor Arabic", "ABC Monument Grotesk", sans-serif;

  /* single source of truth for the brand-element margins, so the logo,
     wordmark and contact block all sit the same, tight distance from every
     edge — a fixed pixel inset rather than a percentage so it stays a
     "few pixels" regardless of viewport size, and identical on every side */
  --edge: 14px;

  --bg-current: var(--grey);

  --vh: 1vh; /* corrected in JS for mobile URL-bar */
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--grey);
  color: var(--ink);
}

body {
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

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

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* ---------- fixed colour backdrop (smooth cross-fade between panels) ---------- */

.bg-fade {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--bg-current);
  transition: background-color 1.15s cubic-bezier(0.45, 0, 0.2, 1);
  pointer-events: none;
}

/* ---------- custom cursor: yellow disc, thin black outline, no blend mode ---------- */

.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  border-radius: 50%;
  background: var(--yellow);
  border: 1.5px solid var(--ink);
  pointer-events: none;
  z-index: 999;
  opacity: 0;
  transform: translate3d(-100px, -100px, 0);
  transition: opacity 0.3s ease;
  will-change: transform;
}

.cursor-dot.is-active { opacity: 1; }

@media (hover: none), (pointer: coarse) {
  .cursor-dot { display: none; }
}

/* only the custom circle should show while using the site with a real
   mouse — hide the system arrow everywhere, including over links */
@media (hover: hover) and (pointer: fine) {
  body,
  a,
  button {
    cursor: none;
  }
}

/* ---------- scroll container ---------- */

.scroller {
  position: relative;
  z-index: 5;
  height: 100vh;
  height: calc(var(--vh, 1vh) * 100);
  overflow-y: scroll;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  /* minimal scrollbar, styled to match the design rather than the browser
     default chrome (Firefox + WebKit/Blink) */
  scrollbar-width: thin;
  scrollbar-color: var(--ink) transparent;
}

.scroller::-webkit-scrollbar {
  width: 5px;
}

.scroller::-webkit-scrollbar-track {
  background: transparent;
}

.scroller::-webkit-scrollbar-thumb {
  background-color: var(--ink);
  opacity: 0.4;
  border-radius: 3px;
}

.panel {
  position: relative;
  height: 100vh;
  height: calc(var(--vh, 1vh) * 100);
  width: 100%;
  overflow: hidden;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: var(--panel-bg, transparent);
}

.panel--grey { --panel-bg: var(--grey); color: var(--ink); }
.panel--pink { --panel-bg: var(--pink); color: var(--ink); }
.panel--yellow { --panel-bg: var(--yellow); color: var(--ink); }

/* once JS is driving the smooth backdrop, let it show through instead of
   the panel's own flat colour (the flat colour remains as the no-JS
   fallback so the page still looks correct without scripting). Used on
   both desktop and mobile now, so panel-to-panel colour changes (grey →
   pink → yellow) cross-fade smoothly everywhere. */
body.bg-enhanced .panel { background: transparent; }

/* ==========================================================================
   Brand elements — logo mark + wordmark
   Each panel carries its own static logo/wordmark markup, used directly on
   mobile. On desktop those copies are hidden completely — instead a single
   persistent "fly" logo and "fly" wordmark (fixed to the viewport) are
   shown, and switching panels simply fades them out, swaps position/colour
   while invisible, and fades them back in. Nothing slides across the page.
   ========================================================================== */

.logo,
.wordmark {
  position: absolute;
  pointer-events: none;
}

/* width is derived from the edge inset itself (not a fixed percentage) so
   the mark's right edge sits exactly --edge from the frame too, matching
   its left edge precisely instead of drifting as the fixed-% width and the
   fixed-px edge fall out of sync at different viewport sizes */
.logo { left: var(--edge); width: calc(100% - 2 * var(--edge)); z-index: 1; }
.wordmark { left: var(--edge); width: 48.4%; z-index: 2; }

.logo--top,
.logo--hero { top: var(--edge); }
.logo--bottom { bottom: var(--edge); }

.wordmark--top { top: var(--edge); }
.wordmark--bottom,
.wordmark--hero { bottom: var(--edge); }

.logo svg,
.wordmark svg {
  display: block;
  width: 100%;
  height: auto;
}

@media (min-width: 861px) {
  .logo,
  .wordmark {
    display: none;
  }
}

/* ---------- the persistent flying logo + wordmark (desktop only) ---------- */

.logo-fly,
.wordmark-fly {
  position: fixed;
  left: var(--edge);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.42s ease;
}

/* the big logo sits BEHIND photos/text (it's a backdrop mark); the
   wordmark/title sits IN FRONT of everything, since in the source design
   the title overlaps the top of the product photo on panel 2 */
.logo-fly { width: calc(100% - 2 * var(--edge)); z-index: 2; }
.wordmark-fly { width: 48.4%; z-index: 6; }

.logo-fly[data-pos="top"],
.wordmark-fly[data-pos="top"] { top: var(--edge); bottom: auto; }

.logo-fly[data-pos="bottom"],
.wordmark-fly[data-pos="bottom"] { bottom: var(--edge); top: auto; }

.logo-fly.is-placed,
.wordmark-fly.is-placed { opacity: 1; }

@media (max-width: 860px) {
  .logo-fly,
  .wordmark-fly { display: none; }
}

.logo-fly__inner,
.wordmark-fly__inner {
  position: relative;
  width: 100%;
}

.logo-fly__inner {
  aspect-ratio: 1709.3 / 251.7;
  opacity: 0;
  transform: translateY(24px);
}

body.is-ready .logo-fly__inner {
  animation: rise-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.5s forwards;
}

.wordmark-fly__inner {
  opacity: 0;
  transform: translateY(24px);
}

body.is-ready .wordmark-fly__inner {
  animation: rise-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) 1s forwards;
}

@keyframes rise-in {
  to { opacity: 1; transform: translateY(0); }
}

.wordmark-fly__inner svg {
  display: block;
  width: 100%;
  height: auto;
}

/* three colour/shape variants stacked in place; only the active one shows */
.logo-variant {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.logo-variant svg {
  display: block;
  width: 100%;
  height: 100%;
}

.logo-fly[data-show="outline"] .logo-variant--outline,
.logo-fly[data-show="black"] .logo-variant--black,
.logo-fly[data-show="yellow"] .logo-variant--yellow {
  opacity: 1;
}

/* the outline mark's resting appearance is simply filled solid — the hero
   intro is the same plain fade + rise as the wordmark (see
   body.is-ready .logo-fly__inner above), not a path-drawing animation. */

.logo-variant--outline path {
  fill: currentColor;
}

/* ==========================================================================
   Panel 1 — hero / loader
   ========================================================================== */

.tagline {
  position: absolute;
  right: var(--edge);
  /* just a couple pixels above the wordmark's own baseline inset — flush
     to the exact same value read as slightly too tight for the text */
  bottom: calc(var(--edge) + 4px);
  display: flex;
  align-items: flex-end;
  gap: clamp(16px, 3vw, 48px);
  text-align: right;
}

.tagline-block {
  margin: 0;
  opacity: 0;
  transform: translateY(18px);
}

body.is-ready .tagline-en {
  animation: rise-in 0.8s cubic-bezier(0.16, 1, 0.3, 1) 1.4s forwards;
}

body.is-ready .tagline-fa {
  animation: rise-in 0.8s cubic-bezier(0.16, 1, 0.3, 1) 1.55s forwards;
}

.tagline-en {
  font-family: var(--font-mono);
  font-size: 21px;
  line-height: 1.2;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.tagline-fa {
  font-family: var(--font-fa);
  font-size: clamp(14px, 1.5vw, 22px);
  line-height: 1.2;
  direction: rtl;
}

/* ==========================================================================
   Panels 2 & 3 — photo + text content
   Measured directly off the source design: the product photo runs tall,
   close to its own full uncropped proportions, and overlaps the top of the
   big bottom logo mark (the photo sits above it, the logo shows through
   below/around it) rather than the two staying in separate bands.
   ========================================================================== */

.photo-box,
.text-box {
  position: absolute;
  overflow: hidden;
  z-index: 3;
}

.photo-box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* the text column sits right next to its photo, separated by the same
   margin used everywhere else (--edge) rather than a big open gap. */
.photo-box--p2 { left: 14.9%; top: 5.4%; width: 41.2%; height: 92%; }
.text-box--p2  { left: 57.5%; top: 11%; width: 40.7%; height: 62%; }

.photo-box--p3 { right: var(--edge); top: calc(32% + 5px); width: 29.6%; height: 65%; }
/* text starts at the same top offset as the English column on panel 2,
   regardless of where its photo sits. Taller than panel 2's column since
   there's clear room below it here (the wordmark sits well further down
   on this panel), and the larger Farsi type needs it. */
.text-box--p3  { left: 26.5%; top: 11%; width: 41.1%; height: 70%; }

.copy {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.copy p {
  margin: 0;
  /* scales with viewport height, not just a flat 20px — a smaller-
     resolution desktop screen has a shorter .text-box (it's a % of vh)
     but was still being asked to hold 20px type, which is what was
     clipping the last lines there. 2vh resolves to exactly 20px at the
     1000px-tall viewport this was designed at, so nothing changes there;
     it only shrinks in step with the box on shorter screens. */
  font-size: clamp(14px, 2vh, 20px);
  line-height: 1.1;
  text-align: justify;
  font-family: var(--font-body);
  letter-spacing: 0.005em;
}

.copy p:nth-child(even) {
  padding-left: 6.8em;
}

.copy--fa {
  justify-content: flex-start;
}

.copy--fa p {
  font-family: var(--font-fa);
  direction: rtl;
  /* same reasoning as .copy p above — 1.9vh resolves to exactly 19px at
     the 1000px-tall viewport this was designed at */
  font-size: clamp(13px, 1.9vh, 19px);
  line-height: 1.3;
  text-align: justify;
  margin: 0;
}

.copy--fa p:nth-child(even) {
  padding-left: 0;
  padding-right: 6.4em;
}

/* kashida justification (see assets/js/kashida.js): each line becomes its
   own block once JS has measured and pre-broken the paragraph, so the
   browser's own reflow-and-wrap is no longer involved — only the final
   pixel or two of each line is left for ordinary inter-word justification
   to close, since the inserted tatweel characters already carry the line
   most of the way to the full column width. Until the script runs, the
   plain .copy--fa p rule above (text-align: justify) is what's visible, so
   the paragraph is never left unstyled. */
.copy--fa .kashida-line {
  display: block;
  white-space: nowrap;
  text-align: justify;
  text-align-last: justify;
}

.copy--fa .kashida-line.is-last {
  text-align-last: right;
}

.reveal {
  opacity: 0;
  transform: translateY(36px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1), transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

.panel.in-view .reveal {
  opacity: 1;
  transform: translateY(0);
}

.reveal--delay1 { transition-delay: 0.08s; }
.reveal--delay2 { transition-delay: 0.2s; }

/* photos fade/slide in as the panel is entered — a touch slower and
   softer than the other reveals so they settle in gently */
.reveal--photo {
  opacity: 0;
  transform: translateY(64px);
  transition: opacity 1.35s cubic-bezier(0.16, 1, 0.3, 1), transform 1.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal--photo.in-view {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   Panel 4 — contact
   Right-aligned, flush to the same right-hand margin as the logo/wordmark.
   ========================================================================== */

.contact {
  position: absolute;
  right: var(--edge);
  /* a little more headroom than the shared edge margin — sitting flush
     with it read as too tight against the top of the page */
  top: calc(var(--edge) + 8px);
  margin: 0;
  font-family: var(--font-mono);
  font-size: 37px;
  line-height: 1.1;
  text-align: right;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  display: grid;
  grid-template-columns: auto auto;
  gap: 0.15em clamp(16px, 2.5vw, 40px);
  justify-content: end;

  /* hidden by default; brought in either by the generic scroll-reveal
     (mobile) or by an explicit JS-timed class (desktop, see below) */
  opacity: 0;
  transform: translateY(36px);
}

/* mobile: no sticky fly system, so the normal "reveal on scroll in" is fine */
@media (max-width: 860px) {
  .panel.in-view .contact {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.2s,
                transform 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.2s;
  }
}

/* desktop: the panel counts as "in view" (and the sticky wordmark starts its
   cross-fade) well before the scroll-snap has actually settled here, which
   made the contact details look tied to the wordmark's movement. So on
   desktop the contact block ignores that early trigger entirely and is
   revealed only once JS decides the page has actually landed — see
   `.contact-show` in main.js, timed independently of the wordmark swap. */
@media (min-width: 861px) {
  .contact.contact-show {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  }
}

.contact dt {
  font-weight: 400;
  opacity: 0.8;
}

.contact dd {
  margin: 0;
}

/* ==========================================================================
   Responsive — stack everything in normal document flow on small screens
   ========================================================================== */

@media (max-width: 860px) {
  /* a panel is no longer itself the snap unit — it just groups one or more
     full-screen "steps" (see .m-step below). This is what lets the English
     and Farsi pages split their photo and text into separate, single-
     purpose screens instead of cramming both onto one panel the user had
     to notice they could scroll further inside. */
  .panel {
    height: auto;
    overflow: visible;
    scroll-snap-align: none;
    scroll-snap-stop: normal;
  }

  /* the real mobile snap unit: one step = one full screen the user lands
     on. Content taller than the screen scrolls internally here (so the
     full text is always reachable) before the next wheel/swipe moves on
     to the next step. On desktop this is switched to display:contents
     further down, so it has zero layout effect there — the existing
     absolutely-positioned desktop design is completely untouched. */
  .m-step {
    height: calc(var(--vh, 1vh) * 100);
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    display: flex;
    flex-direction: column;
    padding: 20px 16px;
    gap: 20px;
  }

  .logo,
  .wordmark,
  .photo-box,
  .text-box,
  .contact {
    position: static;
    left: auto;
    top: auto;
    right: auto;
    bottom: auto;
    width: 100%;
    height: auto;
  }

  .photo-box,
  .text-box {
    overflow: visible;
  }

  /* logo + wordmark fade in like the rest of the content as their step
     comes into view, instead of appearing with no animation at all */
  .logo,
  .wordmark {
    opacity: 0;
    transform: translateY(36px);
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1), transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .panel.in-view .logo,
  .panel.in-view .wordmark,
  .m-step.in-view .logo,
  .m-step.in-view .wordmark {
    opacity: 1;
    transform: translateY(0);
  }

  /* hero: logo top, tagline in the middle, wordmark full-width at the very
     bottom — with just these three items in one step, space-between
     spreads them evenly down the screen */
  .hero .m-step { justify-content: space-between; }
  .hero__tagline.tagline {
    position: static;
    justify-content: space-between;
    text-align: left;
  }
  .tagline-fa { text-align: right; }
  .tagline-en { font-size: 15px; }

  /* the content pages don't repeat the wordmark — it only bookends the
     experience, on the hero and the last page — so panels 2 and 3 stay
     purely photo + text, without the extra logotype on every screen */
  #panel-1 .wordmark,
  #panel-2 .wordmark {
    display: none;
  }

  /* English page, first step: logo stays at the top, the photo sits at
     the bottom of the same screen (same edge padding as everything else,
     just the open space between the two collapses to nothing) */
  .m-step--p2-photo { justify-content: space-between; }

  /* full-size, uncropped photos — the box now simply follows the image's
     own natural proportions at full device width instead of being cropped
     to a fixed aspect ratio */
  .photo-box img { height: auto; object-fit: contain; }
  .reveal--photo { transform: translateY(40px); }

  .text-box--p2, .text-box--p3 { height: auto; }

  .copy { justify-content: flex-start; }

  /* a touch smaller than before — less text height per step means less
     internal scrolling before a swipe reaches the next snap point, which
     is what was making the step-to-step scrolling feel stuck */
  .copy p { font-size: 14px; font-family: var(--font-body); text-align: justify; }
  .copy--fa p {
    /* explicit here, not just inherited from the base rule — otherwise the
       .copy p rule just above it (equal specificity, later in the file on
       mobile) wins the font-family tie-break and silently renders the
       Farsi paragraphs in the Latin body font */
    font-family: var(--font-fa);
    font-size: 13px;
    line-height: 1.2;
    text-align: justify;
  }

  .contact { font-size: 20px; line-height: 1.2; text-align: left; justify-content: start; }

  /* last page: wordmark top and the black logo mark bottom stay where they
     are; the info block now spans the full width between them instead of
     a narrow centered block */
  #panel-3 .m-step { justify-content: space-between; }
  #panel-3 .contact {
    width: 100%;
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 16px;
    row-gap: 0.3em;
    text-align: left;
  }
  #panel-3 .contact dd { text-align: right; }
}

/* desktop safety: the mobile-only step wrapper generates no box at all, so
   it cannot affect the absolutely-positioned desktop layout — children
   resolve their positioned ancestor straight through to .panel, exactly
   as if this wrapper didn't exist in the markup. */
@media (min-width: 861px) {
  .m-step { display: contents; }
}

@media (max-width: 480px) {
  .copy p:nth-child(even) { padding-left: 2.8em; }
  .copy--fa p:nth-child(even) { padding-left: 0; padding-right: 2.8em; }
  .contact { font-size: 16px; }
}
