/* Indian Tribe — home: the mark assembling, and the deck it settles onto
 * -----------------------------------------------------------------------------
 * Two full screens. The mark is fixed and owned by neither: it prints itself on
 * the first and rides up to the masthead of the second, and everything on the
 * deck is positioned relative to where it lands.
 *
 * --flow is written every frame by assemble.js — 0 while the mark holds the
 * landing, 1 once it has settled on the deck. The halves and the dial are keyed
 * off it rather than off a class, so the fly-up tracks the scroll exactly and
 * runs backwards for free when you scroll up.
 */

:root{
  /* driven per-frame from assemble.js — never transitioned, so a backgrounded
     tab cannot come back out of step with itself */
  --veilK:     1;
  --drawK:     0;
  --tagK:      0;
  --ruleK:     0;
  --tagSpread: .42em;
  --flow:      0;

  --mark-w: min(54vw, 96vh, 800px);
  --mark-h: calc(var(--mark-w) / 1.735);     /* the new stacked lockup's aspect */

  --dial-r:    clamp(150px, 26vh, 300px);
  --dial-foot: 11vh;                          /* pivot height off the floor */
}

/* The artwork is the welcome, not the wallpaper: full strength while the mark
   is printing itself, and most of the way out by the time the deck arrives, so
   the photography and the dial are not competing with rosettes. */
/* the cream field is the landing's alone: it hands over completely to the
   rose ground as the preview arrives */
body.home{ --field-weight:calc(.52 - .54 * var(--flow)); }

.story{ position:relative; z-index:2; }

/* No mix-blend-mode. A full-screen blended overlay forces the compositor to
   copy the backdrop and re-blend the whole viewport every frame, and it stops
   everything underneath from being promoted to its own layer — which is most of
   why scrolling felt heavy. Plain alpha over cream is indistinguishable. */
.grain{
  position:fixed; inset:0;
  z-index:60;
  pointer-events:none;
  opacity:.22;
  transform:translateZ(0);        /* its own layer, so scrolling never repaints it */
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/>\
<feColorMatrix type='saturate' values='0'/></filter>\
<rect width='140' height='140' filter='url(%23n)' opacity='.34'/></svg>");
}

/* ── screens ────────────────────────────────────────────────────────────────
   Plain vertical scroll. Every screen is a snap stop with `scroll-snap-stop:
   always`, so one flick of the wheel carries you to exactly the next one. */

.screen{
  position:relative;
  z-index:10;
  height:100vh;
  overflow:hidden;
}

/* ── the mark ───────────────────────────────────────────────────────────────
   Fixed, and outside both screens: one element makes the whole journey. */

.mark{
  position:fixed;
  left:50%; top:50%;
  z-index:30;
  width:var(--mark-w);
  transform:translate(-50%,-50%);
  pointer-events:none;
  /* no resting filter: a drop-shadow here means the whole 333-node lockup is
     re-rasterised through a blur on every frame it changes, which is every
     frame of the reveal */
  transition:filter .5s var(--ease-soft);
  /* This is a 333-path SVG, fixed, covering most of the screen. Unpromoted, the
     browser repaints every one of those paths on every scroll tick. It is the
     one element on the page that genuinely earns a layer of its own. */
  will-change:transform;
}
.mark svg, .mark img{
  display:block;
  position:relative;
  z-index:1;
  width:100%; height:auto;
  overflow:visible;               /* fragments fly outside the lockup */
}
.mark-flat{ transform:translate(-50%,-50%); }

/* the soft cast that seats under the mark as it lands, its own element so the
   333-path lockup is never re-rasterised through a blur */
.mark-cast{
  position:absolute;
  left:50%; bottom:15%;
  width:60%; height:13%;
  transform:translateX(-50%);
  z-index:0;
  opacity:0;
  pointer-events:none;
  background:radial-gradient(50% 50% at 50% 50%,
    rgba(46,30,16,.30) 0%, rgba(46,30,16,.12) 42%, rgba(46,30,16,0) 72%);
  filter:blur(11px);
}

/* while a side of the deck is being previewed the mark steps back with the rest */
html[data-pick] .mark{ filter:blur(1.8px) saturate(.76); }

.screen-mark::after{                   /* first-paint veil */
  content:"";
  position:absolute; inset:0;
  background:var(--paper);
  pointer-events:none;
  opacity:var(--veilK);
  z-index:20;
}

/* the boundary, lifted from the lockup artwork rather than redrawn */
.chauk{
  position:absolute; inset:0;
  background:url("../assets/boundary.webp") center / 100% 100% no-repeat;
  opacity:calc(var(--drawK) * .95);
  transform:scale(calc(1.075 - .075 * var(--drawK)));
  transform-origin:center;
  filter:blur(calc((1 - var(--drawK)) * 7px));
  pointer-events:none;
}
/* The lattice takes colour where the pointer is. The art is a raster, so the
   colour is laid over as a wheel of the wordmark's own colours and cut twice:
   once to the drawing, so only its line work colours and not the space between
   it, and once to a disc at the pointer. Compositing the two is what makes it
   read as filling in rather than a coloured shape chasing the mouse. */
.chauk::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:conic-gradient(from 0deg,
    #f15928, #f4862a, #187c89, #0f2940, #892a8c, #a02168, #d9252b, #f15928);
  -webkit-mask-image:url("../assets/boundary.webp"),
    radial-gradient(circle at var(--hx,50%) var(--hy,50%),
      #000 0, #000 var(--hr,0px), transparent calc(var(--hr,0px) + 150px));
          mask-image:url("../assets/boundary.webp"),
    radial-gradient(circle at var(--hx,50%) var(--hy,50%),
      #000 0, #000 var(--hr,0px), transparent calc(var(--hr,0px) + 150px));
  -webkit-mask-size:100% 100%, auto;        mask-size:100% 100%, auto;
  -webkit-mask-repeat:no-repeat, no-repeat; mask-repeat:no-repeat, no-repeat;
  -webkit-mask-position:center, center;     mask-position:center, center;
  -webkit-mask-composite:source-in;         mask-composite:intersect;
  opacity:var(--latticeK, 0);
  transition:opacity .3s ease;
}

/* ── the landing's caption ──────────────────────────────────────────────── */

.caption{
  position:absolute;
  left:50%;
  top:calc(50% + var(--mark-h) * .5 + clamp(20px, 3.4vh, 46px));
  transform:translateX(-50%);
  opacity:var(--tagK);
  pointer-events:none;
}
.tagline{
  margin:0;
  display:flex; align-items:center;
  gap:clamp(9px,1.1vw,17px);
  white-space:nowrap;
  font-size:clamp(10px,.95vw,14px);
  font-weight:600;
  text-transform:uppercase;
  color:var(--ink);
}
.tagline .words{
  letter-spacing:calc(.34em + var(--tagSpread));
  text-indent:calc(.34em + var(--tagSpread));
}
.rule{
  display:block; height:1px;
  width:calc(clamp(34px,5.4vw,96px) * var(--ruleK));
  background:linear-gradient(90deg, rgba(20,17,15,0), rgba(20,17,15,.55));
}
.rule-r{ transform:scaleX(-1); }
.pip{
  display:block; width:6px; height:6px;
  background:var(--red);
  transform:rotate(45deg) scale(var(--ruleK));
}

/* ── the scroll cue ─────────────────────────────────────────────────────── */

.cue{
  position:absolute;
  left:50%; bottom:clamp(20px,4.2vh,46px);
  transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; gap:10px;
  background:none; border:0; padding:6px 10px;
  cursor:pointer;
  opacity:calc(var(--tagK) * (1 - var(--flow) * 3));
}
.cue-word{
  font-size:10px; font-weight:600; letter-spacing:.32em; text-indent:.32em;
  text-transform:uppercase; color:var(--ink-2);
}
.cue-rail{
  display:block; position:relative;
  width:1px; height:clamp(28px,5vh,52px);
  background:var(--rule);
  overflow:hidden;
}
.cue-rail i{
  position:absolute; left:0; top:0;
  width:1px; height:40%;
  background:var(--red);
  animation:cueRun 2.1s var(--ease-soft) infinite;
}
@keyframes cueRun{
  0%{ transform:translateY(-100%); }
  60%,100%{ transform:translateY(250%); }
}
.cue:hover .cue-word{ color:var(--red); }

/* ═══ the preview ══════════════════════════════════════════════════════════
   One run of the work, films and photographs mixed, at mixed sizes and mixed
   aspects, each turned a few degrees off true, some mounted on a white print
   border. The cards never change as they travel — their transform is written
   once at build — so the only thing that moves per frame is the belt. */

.screen-deck{
  pointer-events:none;
  --clock-lift:14px;              /* lifted, as on the portfolio */
}
.screen-deck.is-live{ pointer-events:auto; }

.scatter{
  position:absolute;
  left:0; right:0;
  /* full screen now, so the parabola's arms can run right into the bottom
     corners without being clipped by the box they sit in */
  top:0; height:100vh;
  display:block;
  overflow:hidden;
  text-decoration:none;
  cursor:pointer;
  transform:translateY(calc((1 - var(--flow)) * 34vh));
  opacity:calc(var(--flow) * 2.2 - .5);
}
/* the arc is drawn in WebGL: the media elements are only texture sources */
.sc-gl{
  position:absolute; inset:0;
  width:100%; height:100%;
  display:block;
  pointer-events:none;
}
.sc-pool{
  position:absolute;
  width:0; height:0;
  overflow:hidden;
  opacity:0;
  pointer-events:none;
}

/* the way in reads on the label, not on a hover state over the pictures. It
   darkens rather than going red: the portfolio's own dial has no red in it,
   and the word turning a different colour here was the only thing making the
   two screens look like two different instruments. */
.scatter:hover ~ .clock-nav .radial-item,
.scatter:focus-visible ~ .clock-nav .radial-item{ color:#111; }

/* the clock arrives with the scroll */
.screen-deck .clock-nav,
.screen-deck .clock-hit-layer,
.screen-deck .clock-hud{
  transform:translateX(-50%) translateY(calc((1 - var(--flow)) * 26vh));
  opacity:calc(var(--flow) * 2.4 - 1.3);
}
.screen-deck .clock-hit-layer{ pointer-events:none; }
/* the label takes the pointer too, so the whole PORTFOLIO button is the way in
   and not just the smaller invisible hit box sitting behind it */
.screen-deck.is-live .clock-hit,
.screen-deck.is-live .radial-item{ pointer-events:auto; }
.screen-deck.is-live .radial-item{ cursor:pointer; }

/* entrance B: the clock is thrown up from under the floor with the cards */
.screen-deck.is-thrown .clock-nav,
.screen-deck.is-thrown .clock-hit-layer,
.screen-deck.is-thrown .clock-hud{
  animation:clockThrow 0.80s var(--ease-out) both;
}
@keyframes clockThrow{
  0%   { transform:translateX(-50%) translateY(46vh); opacity:0; }
  70%  { opacity:1; }
  100% { transform:translateX(-50%) translateY(0); opacity:1; }
}

/* ── on into the story ──────────────────────────────────────────────────── */

.onward{
  position:absolute;
  /* off the centre line, where the dial's pivot sits — and on the left,
     because the toggles own the other corner */
  left:clamp(18px,3.4vw,62px); bottom:clamp(12px,2.2vh,24px);
  display:flex; flex-direction:row-reverse; align-items:center; gap:11px;
  background:none; border:0; padding:6px 12px;
  cursor:pointer;
  z-index:55;
  opacity:calc(var(--flow) * 3 - 2);
}
.onward .eyebrow{ transition:color .3s var(--ease-soft); }
.onward:hover .eyebrow{ color:var(--red); }
.onward-rail{
  display:block; position:relative;
  width:1px; height:clamp(20px,3vh,32px);
  background:var(--rule);
  overflow:hidden;
}
.onward-rail i{
  position:absolute; left:0; top:0;
  width:1px; height:44%;
  background:var(--red);
  animation:cueRun 2.4s var(--ease-soft) infinite;
}

/* ── portrait ───────────────────────────────────────────────────────────── */

@media (orientation:portrait), (max-width:760px){
  :root{ --mark-w: min(84vw, 62vh, 620px); }
  .tagline{ font-size:clamp(8px,2.3vw,11px); }
  .tagline .words{
    letter-spacing:calc(.28em + var(--tagSpread));
    text-indent:calc(.28em + var(--tagSpread));
  }
  .scatter{ top:15vh; height:56vh; }
  .screen-deck .clock-nav,
  .screen-deck .clock-hit-layer,
  .screen-deck .clock-hud{
    transform:translateX(-50%) translateY(calc((1 - var(--flow)) * 26vh)) scale(.78);
    transform-origin:center bottom;
  }
}

/* ── Preview Screen Dial Control Panel ─────────────────────────────────── */
.dial-panel{position:fixed;top:70px;right:18px;z-index:99;width:290px;max-height:calc(100vh - 90px);overflow-y:auto;background:rgba(18,15,13,.88);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid rgba(255,255,255,.16);border-radius:12px;color:#f4f4f1;font-family:Arial,Helvetica,sans-serif;font-size:11px;padding:14px;box-shadow:0 16px 40px rgba(0,0,0,.4);user-select:none;transition:transform .3s ease,opacity .3s ease}
.dial-panel.collapsed .dial-body{display:none}
.dial-panel.collapsed{width:180px;padding:10px 14px}
.dial-header{display:flex;justify-content:space-between;align-items:center;font-weight:700;letter-spacing:.09em;text-transform:uppercase;font-size:11px;color:#fff;cursor:pointer}
.dial-panel:not(.collapsed) .dial-header{padding-bottom:10px;border-bottom:1px solid rgba(255,255,255,.12)}
.dial-header button{background:rgba(255,255,255,.12);border:none;color:#fff;width:22px;height:22px;border-radius:4px;cursor:pointer;display:grid;place-items:center;font-weight:bold;font-size:13px;line-height:1}
.dial-header button:hover{background:rgba(255,255,255,.28)}
.dial-group{margin-top:10px}
.dial-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;color:rgba(255,255,255,.82);font-size:11px}
.dial-val{font-weight:700;color:#c8102e;font-family:monospace;font-size:11px}
.dial-slider{width:100%;height:4px;background:rgba(255,255,255,.2);border-radius:2px;outline:none;accent-color:#c8102e;cursor:pointer}
.dial-actions{margin-top:14px;display:flex;gap:8px}
.dial-btn{flex:1;padding:8px 6px;background:#c8102e;color:#fff;border:none;border-radius:6px;font-weight:700;font-size:10px;letter-spacing:.06em;cursor:pointer;text-transform:uppercase;transition:background .2s ease}
.dial-btn:hover{background:#e63946}
.dial-btn.sec{background:rgba(255,255,255,.12);color:#ddd}
.dial-btn.sec:hover{background:rgba(255,255,255,.25);color:#fff}
.dial-toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(20px);background:#111;color:#fff;border:1px solid rgba(255,255,255,.22);padding:10px 22px;border-radius:30px;font-size:12px;font-weight:600;letter-spacing:.05em;pointer-events:none;opacity:0;transition:opacity .3s ease,transform .3s ease;z-index:1000;box-shadow:0 10px 30px rgba(0,0,0,.45)}
.dial-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

@media(max-width:900px){
  .dial-panel{top:58px;right:10px;width:240px;padding:10px;font-size:10px}
}
