﻿<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>TJ · DROP 03 — American Streetwear, Morandi Palette</title>
  <meta name="description" content="TJ — Oversize 300G cotton tees, washed docker caps, heritage shoes. Made in China. Morandi palette, streetstyle fit."/>
  <link rel="preload" as="image" href="assets/hero_v3/optimized/hero_poster.webp?v=20" fetchpriority="high" />
  <link rel="stylesheet" href="css/main.css?v=23" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">
  <link rel="icon" type="image/x-icon" href="/favicon.ico">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  <link rel="shortcut icon" href="/favicon.ico">

<!-- TJ SiteOS live install: head start -->
<link rel="stylesheet" href="/tj-siteos-install.css">
<link rel="stylesheet" href="/robot-widget.css">
<link rel="icon" href="/assets/brand/favicon.svg" type="image/svg+xml">
<!-- TJ SiteOS live install: head end -->
</head>
<body data-page="home">

<nav class="nav">
  <div class="nav-inner">
    <a href="index.html" class="nav-brand">TJ</a>
    <div class="nav-links">
      <a href="shop.html?cat=tees">TEES</a>
      <a href="shop.html?cat=hats">HATS</a>
      <a href="shop.html?cat=shoes">SHOES</a>
      <a href="model.html">LOOK</a>
    </div>
    <div class="nav-right">
      <a href="cart.html" class="cart-btn">BAG<span class="cart-count"></span></a>
    </div>
  </div>
</nav>

<!-- Hero · desktop clear video + mobile static poster -->
<section class="hero">
  <div class="hero-media" id="heroMulti">
    <img class="hero-poster" src="assets/hero_v3/optimized/hero_poster.webp?v=20" alt="" fetchpriority="high" decoding="async" />
    <!-- 1. 高楼街区跳跃，清晰桌面版 -->
    <video data-src="assets/hero_v3/optimized/hero_desktop_city.mp4?v=21" muted playsinline preload="none" disablepictureinpicture controlslist="nodownload"
           poster="assets/hero_v3/optimized/hero_poster.webp?v=20"
           style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 35%;display:block;opacity:1;transition:opacity 1.2s ease-in-out"></video>
    <!-- 2. 晾衣服，清晰桌面版 -->
    <video data-src="assets/hero_v3/optimized/hero_desktop_clothes.mp4?v=20" muted playsinline preload="none" disablepictureinpicture controlslist="nodownload"
           poster="assets/hero_v3/optimized/hero_poster.webp?v=20"
           style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 35%;display:block;opacity:0;transition:opacity 1.2s ease-in-out"></video>
    <!-- 3. 别墅跳，清晰桌面版 -->
    <video data-src="assets/hero_v3/optimized/hero_desktop_jump.mp4?v=20" muted playsinline preload="none" disablepictureinpicture controlslist="nodownload"
           style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 35%;display:block;opacity:0;transition:opacity 1.2s ease-in-out"></video>
  </div>
  <div class="hero-inner">
    <div class="hero-top">
      <span class="hero-drop hype">DROP 03 · FW26</span>
      <div class="hero-meta">TJ STREETWEAR<br/>CHINA · MORANDI</div>
    </div>
    <div class="hero-bottom">
      <div class="hero-title">
        <div class="eyebrow">NEW COLLECTION</div>
        <h1>Soft<br/>Dye,<br/>Hard<br/>Cut.</h1>
      </div>
      <div class="hero-cta">
        <a class="btn btn-light" href="shop.html?cat=tees">SHOP THE DROP</a>
        <a class="btn btn-ghost" href="model.html">SHOP THE LOOK</a>
      </div>
    </div>
  </div>
</section>

<!-- Tees -->
<section class="section">
  <div class="container">
    <div class="section-head">
      <div>
        <span class="eyebrow">LOT Nº 10–18</span>
        <h2>Oversize<br/>Cotton Tees.</h2>
      </div>
      <a href="shop.html?cat=tees" class="btn btn-primary">SEE ALL 9</a>
    </div>
    <div class="grid grid-3 home-tees"></div>
  </div>
</section>

<!-- Hats -->
<section class="section" style="background:rgba(26,26,26,0.03);">
  <div class="container">
    <div class="section-head">
      <div>
        <span class="eyebrow">LOT Nº 01–09</span>
        <h2>Washed<br/>Docker Caps.</h2>
      </div>
      <a href="shop.html?cat=hats" class="btn btn-primary">SEE ALL 9</a>
    </div>
    <div class="grid home-hats"></div><!-- 4 cols 1 row: 4 hats sneak peek -->

  </div>
</section>

<!-- Shoes -->
<section class="section">
  <div class="container">
    <div class="section-head">
      <div>
        <span class="eyebrow">LOT Nº 19–24</span>
        <h2>Heritage<br/>Footwear.</h2>
      </div>
      <a href="shop.html?cat=shoes" class="btn btn-primary">SEE ALL 6</a>
    </div>
    <div class="grid grid-3 home-shoes"></div>
  </div>
</section>

<!-- Manifesto strip -->
<section class="section" style="background:var(--ink);color:var(--bg);padding:128px 0;">
  <div class="container" style="text-align:center;">
    <span class="eyebrow" style="color:rgba(255,255,255,0.6)">MANIFESTO</span>
    <h2 style="max-width:18ch;margin:24px auto;color:var(--bg);font-size:clamp(28px,4.5vw,72px)">
      Garment-dyed.<br/>Pre-shrunk.<br/>Made to soften.
    </h2>
    <p style="max-width:52ch;margin:0 auto;opacity:0.7;font-size:14px;line-height:1.8;letter-spacing:0.02em">
      12 Morandi-calibrated colorways. 300G combed cotton. Oversize boxy cut with dropped shoulders. Made in China, pre-washed so every piece arrives soft and worn-in.
    </p>
  </div>
</section>

<footer>
  <div class="container">
    <div>
      <h4>TJ</h4>
      <p style="font-size:11px;opacity:0.6;letter-spacing:0.1em;line-height:1.6">American streetwear, Morandi palette. Made in China.</p>
    </div>
    <div>
      <h4>Shop</h4>
      <a href="shop.html?cat=tees">Tees</a>
      <a href="shop.html?cat=hats">Hats</a>
      <a href="shop.html?cat=shoes">Shoes</a>
      <a href="model.html">Shop the Look</a>
    </div>
    <div>
      <h4>Info</h4>
      <a href="#">Returns</a>
      <a href="#">Shipping</a>
      <a href="#">Fabric &amp; Care</a>
      <a href="#">Contact</a>
    </div>
  </div>
  <div class="footer-bottom">© 2026 TJ · DROP 03 · FW26</div>
</footer>

<script src="js/data.js?v=18"></script>
<script src="js/cart.js?v=10"></script>
<script src="js/i18n.js?v=3"></script>
<script src="js/main.js?v=26"></script>
<script>
/* Hero 4 视频 · v5 v3 · 2026-04-19 · 根治冻帧+卡壳+重复帧
 *
 * 问题诊断:
 *   - 之前同时 play 两个 video + 同时触发 opacity transition = GPU 抢占,
 *     第二个 video 有时停在首帧 (重复帧) 或 1-2 秒 (卡壳).
 *   - setTimeout 驱动 fade, 没等下一个 video 真正 "playing" 就让它可见,
 *     显示的是 poster 或 paused 第一帧 = 视觉冻结.
 *
 * v3 策略:
 *   1. 下一个视频先 load + play, 监听 `playing` 事件 (真的在绘帧了)
 *   2. 然后**才**把它 opacity 从 0 → 1, 同时当前 opacity → 0
 *   3. opacity transition 只在切换一小段启用, 完了移除 transition 避重绘
 *   4. 旧视频淡出完整 1.2s 才 pause + currentTime=0, 不跟新视频同时播
 *   5. 每个视频首次只在需要前 1.2s 预加载, 避免同时 4 个 video decode 抢 GPU
 */
(function heroLoop(){
  var box = document.getElementById('heroMulti');
  if (!box) return;
  var vids = Array.prototype.slice.call(box.querySelectorAll('video'));
  if (vids.length < 2) return;
  var mobileStatic = window.matchMedia && window.matchMedia('(max-width: 760px), (prefers-reduced-motion: reduce)').matches;
  if (mobileStatic) {
    vids.forEach(function(v){ try { v.removeAttribute('src'); v.load(); } catch(e){} });
    box.classList.add('hero-static');
    return;
  }
  vids.forEach(function(v, i){
    var src = v.getAttribute('data-src');
    if (src) v.src = src;
    v.preload = i === 0 ? 'auto' : 'none';
  });
  var N = vids.length;
  var active = 0;
  var FADE_MS = 1200;
  var switching = false;

  // 初始化: 只有当前这条可见, 其它隐藏 pause
  vids.forEach(function(v, i){
    v.style.transition = 'none';
    v.style.opacity = i === 0 ? '1' : '0';
    v.muted = true;
    v.loop = false; // 我们自己控制
    if (i !== 0) { try { v.pause(); } catch(e){} }
  });

  function tryPlay(v){
    var p = v.play();
    if (p && p.then){
      return p.catch(function(){});
    }
    return Promise.resolve();
  }

  function whenReady(v){
    // 等视频真的能开始绘帧 (HAVE_FUTURE_DATA = 3 以上)
    return new Promise(function(resolve){
      if (v.readyState >= 3) return resolve();
      var done = false;
      function ok(){ if (done) return; done = true;
        v.removeEventListener('canplay', ok);
        v.removeEventListener('playing', ok);
        resolve();
      }
      v.addEventListener('canplay', ok, { once: true });
      v.addEventListener('playing', ok, { once: true });
      // 兜底 1.5s
      setTimeout(ok, 1500);
    });
  }

  function switchTo(nextIdx){
    if (switching || nextIdx === active) return;
    switching = true;
    var cur = vids[active];
    var nxt = vids[nextIdx];

    nxt.currentTime = 0;
    // 先静默把下一个启动, 但它还是 opacity:0 用户看不到
    tryPlay(nxt).then(function(){ return whenReady(nxt); }).then(function(){
      // 真的在绘帧了, 才开启 transition + 淡入
      nxt.style.transition = 'opacity ' + FADE_MS + 'ms ease-in-out';
      cur.style.transition = 'opacity ' + FADE_MS + 'ms ease-in-out';
      // 强制 reflow 让 transition 生效
      void nxt.offsetWidth;
      nxt.style.opacity = '1';
      cur.style.opacity = '0';

      setTimeout(function(){
        // 旧的停, 下次再用时从 0 开始
        try { cur.pause(); } catch(e){}
        cur.currentTime = 0;
        // 卸 transition 避免不切换时重绘
        cur.style.transition = 'none';
        nxt.style.transition = 'none';
        active = nextIdx;
        switching = false;
        scheduleNext();
      }, FADE_MS + 50);
    });
  }

  function scheduleNext(){
    var v = vids[active];
    var next = (active + 1) % N;

    function go(){
      var dur = v.duration;
      if (!dur || isNaN(dur) || dur === Infinity) dur = 6;
      // 淡入需要 FADE_MS + 视频启动缓冲 400ms → 提前 1.6s 开始切
      var switchAt = Math.max(500, (dur * 1000) - FADE_MS - 400);
      var timerId = setTimeout(function(){
        switchTo(next);
      }, switchAt);
      // ended 兜底 (若 setTimeout 被节流)
      v.addEventListener('ended', function onEnd(){
        v.removeEventListener('ended', onEnd);
        clearTimeout(timerId);
        if (!switching) switchTo(next);
      }, { once: true });
    }
    if (v.readyState >= 1) go();
    else v.addEventListener('loadedmetadata', go, { once: true });
  }

  // 启动
  tryPlay(vids[0]).then(function(){ return whenReady(vids[0]); }).then(scheduleNext);

  // iOS 兜底: 用户首次点击页面任意位置时, 如果视频因自动播放策略未启动, 再推一次
  document.addEventListener('click', function once(){
    var v = vids[active];
    if (v.paused) tryPlay(v);
    document.removeEventListener('click', once);
  });
})();
</script>

<!-- TJ SiteOS live install: body start -->
<script src="/tj-siteos-install.js" defer></script>
<script src="/robot-widget.js" defer></script>
<!-- TJ SiteOS live install: body end -->
</body>
</html>








