/* spec-handoff.jsx — Developer rules, token map, JS patterns, checklist */

const TokenMapRow = ({ ds, css, value, note }) => (
  <div style={{
    display:'grid', gridTemplateColumns:'140px 180px 140px 1fr',
    padding:`${S[2]}px ${S[5]}px`, borderBottom:`1px solid ${T.n200}`,
    background:T.paper, alignItems:'center', gap:S[3],
  }}>
    <span className="mono" style={{ fontSize:11, letterSpacing:'.08em', color:T.neon }}>{ds}</span>
    <span className="mono" style={{ fontSize:10, letterSpacing:'.08em', color:T.n500 }}>{css}</span>
    <span className="mono" style={{ fontSize:11, letterSpacing:'.06em', color:T.ink }}>{value}</span>
    <span style={{ fontSize:12, color:T.n500 }}>{note}</span>
  </div>
);

const TokenMapHeader = () => (
  <div style={{
    display:'grid', gridTemplateColumns:'140px 180px 140px 1fr',
    padding:`${S[2]}px ${S[5]}px`, background:T.bone2, borderBottom:`1px solid ${T.ink}`, gap:S[3],
  }}>
    {['DS token', 'CSS custom prop', 'value', 'when to use'].map(h => (
      <span key={h} className="mono" style={{ fontSize:9, letterSpacing:'.2em', textTransform:'uppercase', opacity:.6 }}>{h}</span>
    ))}
  </div>
);

const TokenMapSection = () => (
  <Sub no="5.1" title="Token → CSS custom property map">
    <div style={{ border:`1px solid ${T.ink}` }}>
      <TokenMapHeader/>
      <TokenMapRow ds="T.ink"        css="--color-ink"      value="#0a0a0a"  note="Body text, borders, button backgrounds, footer" />
      <TokenMapRow ds="T.bone"       css="--color-bone"     value="#f5f3ee"  note="Page background, announcement bar text on dark" />
      <TokenMapRow ds="T.paper"      css="--color-paper"    value="#ffffff"  note="Cards, inputs, cart drawer, product detail" />
      <TokenMapRow ds="T.neon"       css="--color-neon"     value="#ff2ec4"  note="CTA hover, live dot, footer col headings, active borders" />
      <TokenMapRow ds="T.yellow"     css="--color-yellow"   value="#eaff00"  note="Sale badges, highlight tape, energy moments — not CTA" />
      <TokenMapRow ds="T.chrome"     css="--color-chrome"   value="#cfcdc8"  note="Neutral mid, image placeholders" />
      <TokenMapRow ds="T.n200"       css="--color-n200"     value="#e3e0d8"  note="Dividers, subtle borders, bone hover" />
      <TokenMapRow ds="T.n400"       css="--color-n400"     value="#8a8884"  note="Disabled text, muted labels, metadata" />
      <TokenMapRow ds="T.n500"       css="--color-n500"     value="#4a4844"  note="Body copy on light bg, secondary text" />
      <TokenMapRow ds="T.positive"   css="--color-positive" value="#1f8a4c"  note="In-stock dot only — not for backgrounds" />
      <TokenMapRow ds="T.negative"   css="--color-negative" value="#c53030"  note="Error states, last-N dot, form validation" />
      <TokenMapRow ds="S[1]"         css="--space-1"        value="4px"      note="Icon inner padding, micro gaps" />
      <TokenMapRow ds="S[3]"         css="--space-3"        value="12px"     note="Tight internal spacing (card info, list items)" />
      <TokenMapRow ds="S[5]"         css="--space-5"        value="24px"     note="Standard component gap" />
      <TokenMapRow ds="S[7]"         css="--space-7"        value="48px"     note="Page gutter (default desktop)" />
      <TokenMapRow ds="M.fast"       css="--dur-fast"       value="120ms"    note="Hover states (button bg, image scale prep)" />
      <TokenMapRow ds="M.base"       css="--dur-base"       value="200ms"    note="UI interactions (tabs, accordion, quick-add)" />
      <TokenMapRow ds="M.slow"       css="--dur-slow"       value="360ms"    note="Page transitions, image zoom" />
      <TokenMapRow ds="M.spring"     css="--dur-spring"     value="480ms"    note="Cart drawer, modals, toasts" />
    </div>
    <DevNote>↳ easing: --ease-standard = cubic-bezier(.2,.8,.2,1) for all · --ease-spring = cubic-bezier(.5,1.6,.4,1) for drawer only</DevNote>
  </Sub>
);

const RulesSection = () => (
  <Sub no="5.2" title="Implementation rules">
    <div style={{ border:`1px solid ${T.ink}` }}>
      <div style={{ display:'grid', gridTemplateColumns:'48px 1fr auto', padding:`${S[2]}px ${S[5]}px`, background:T.bone2, borderBottom:`1px solid ${T.ink}`, gap:S[4] }}>
        {['#', 'Rule', 'Priority'].map(h => (
          <span key={h} className="mono" style={{ fontSize:9, letterSpacing:'.2em', textTransform:'uppercase', opacity:.6 }}>{h}</span>
        ))}
      </div>
      <Rule no="01" title="Never hardcode color hex values in section Liquid or CSS" status="required">
        Always reference --color-* CSS custom properties. Hardcoded hex breaks theme editor customization.
      </Rule>
      <Rule no="02" title="Type direction C is locked — no Fraunces in production" status="required">
        Direction C (Helvetica + Mono accents) is the approved brand direction from F1B. Do not load Fraunces unless explicitly unlocked by client.
      </Rule>
      <Rule no="03" title="No border-radius on buttons, cards, or product images" status="required">
        Brand is rectilinear. border-radius: 0 everywhere except --radius-md (8px) on price chips only.
      </Rule>
      <Rule no="04" title="Neon pink (#ff2ec4) is for CTA hover, live dots, and active state — not fills" status="required">
        Never use neon as a section background or card fill. Yellow (#eaff00) is for sale/highlight tape only.
      </Rule>
      <Rule no="05" title="All transition durations from CSS vars — no magic numbers" status="required">
        Use var(--dur-fast), var(--dur-base), etc. easing always var(--ease-standard) except cart drawer which uses var(--ease-spring).
      </Rule>
      <Rule no="06" title="Add-to-cart is always async — never full page reload" status="required">
        POST to /cart/add.js · update cart count · dispatch glose:cart:open. The drawer slides in without navigation.
      </Rule>
      <Rule no="07" title="Images: always srcset + loading=lazy (except hero above fold)" status="required">
        Use Shopify image_url filter with widths: [400, 600, 800, 1200]. Hero: loading=eager, fetchpriority=high.
      </Rule>
      <Rule no="08" title="Product card quick-add via CSS + class toggle — no separate AJAX call on hover" status="recommended">
        The quick-add bar is always rendered, hidden below by translateY(100%). JS only toggles .is-hovered class.
      </Rule>
      <Rule no="09" title="Lookbook parallax: CSS-only scroll-driven on supported browsers, static fallback" status="recommended">
        Use @supports (animation-timeline: scroll()) for native scroll-driven animation. Fallback: no parallax. No IntersectionObserver parallax (janky on iOS).
      </Rule>
      <Rule no="10" title="Monospace labels always uppercase — set in CSS, not in Liquid template" status="required">
        .mono class applies text-transform: uppercase · letter-spacing: 0.18em. Never write uppercase in Liquid t().
      </Rule>
      <Rule no="11" title="Mobile: sticky CTA bar on PDP (fixed bottom), not inline ATC button" status="recommended">
        On viewport &lt; 768px, show a fixed bottom bar with product title + ATC. The inline form remains for no-JS fallback.
      </Rule>
      <Rule no="12" title="Cart drawer z-index: 20 (drawer) · overlay: 30 — always above header (10)" status="required">
        z-index ladder: base 0 · sticky 10 · drawer 20 · overlay 30 · modal 40 · toast 50. Never go outside these.
      </Rule>
    </div>
  </Sub>
);

const JSPatternsSection = () => (
  <Sub no="5.3" title="JS patterns (glose.js)">
    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:S[5] }}>
      <div>
        <div className="mono" style={{ fontSize:10, letterSpacing:'.18em', color:T.neon, marginBottom:S[2] }}>CART — ASYNC ADD + DRAWER</div>
        <pre style={{ background:T.ink, color:'#cfcdc8', padding:S[5], fontSize:11, lineHeight:1.7, fontFamily:"'JetBrains Mono',monospace", margin:0, border:`1px solid ${T.ink}`, overflow:'auto' }}>
{`async function addToCart(formData) {
  const res = await fetch('/cart/add.js', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(formData),
  });
  if (!res.ok) throw await res.json();
  await refreshCart();
  document.dispatchEvent(
    new CustomEvent('glose:cart:open')
  );
}

async function refreshCart() {
  const res = await fetch('/cart.js');
  const cart = await res.json();
  updateCartCount(cart.item_count);
  renderCartItems(cart.items);
}`}
        </pre>
      </div>
      <div>
        <div className="mono" style={{ fontSize:10, letterSpacing:'.18em', color:T.neon, marginBottom:S[2] }}>DROP COUNTDOWN</div>
        <pre style={{ background:T.ink, color:'#cfcdc8', padding:S[5], fontSize:11, lineHeight:1.7, fontFamily:"'JetBrains Mono',monospace", margin:0, border:`1px solid ${T.ink}`, overflow:'auto' }}>
{`function initCountdown(el) {
  const target = new Date(
    el.dataset.dropDate
  ).getTime();

  const tick = () => {
    const now = Date.now();
    const diff = target - now;
    if (diff <= 0) {
      el.closest('.countdown')
        ?.remove();
      return;
    }
    const d = Math.floor(diff/864e5);
    const h = Math.floor(diff/36e5) % 24;
    const m = Math.floor(diff/6e4) % 60;
    const s = Math.floor(diff/1e3) % 60;
    el.querySelector('[data-d]')
      .textContent = String(d).padStart(2,'0');
    el.querySelector('[data-h]')
      .textContent = String(h).padStart(2,'0');
    el.querySelector('[data-m]')
      .textContent = String(m).padStart(2,'0');
    el.querySelector('[data-s]')
      .textContent = String(s).padStart(2,'0');
  };
  tick();
  setInterval(tick, 1000);
}`}
        </pre>
      </div>
    </div>
    <DevNote>↳ All custom events prefixed glose: — listen on document · never on specific elements (avoids DOM race conditions)</DevNote>
  </Sub>
);

const ChecklistSection = () => {
  const items = {
    'Architecture': [
      ['Set up theme/ folder from Dawn 14+', true],
      ['Add glose.css with all CSS custom properties', true],
      ['Add glose.js with cart, drawer, countdown, header scroll', true],
      ['Create icons.svg sprite', true],
      ['Configure settings_schema.json (colors, type direction, layout)', true],
      ['Set up theme.liquid with CSS var injection', true],
    ],
    'Sections': [
      ['announcement-bar.liquid', true],
      ['header.liquid (sticky + transparent-on-hero)', true],
      ['footer.liquid (4-col, ink bg)', true],
      ['hero.liquid (with optional countdown)', true],
      ['collection-grid.liquid (2–4 col, quick-add)', true],
      ['product-detail.liquid (variant picker, async ATC)', true],
      ['lookbook-grid.liquid (CSS grid mosaic)', true],
      ['rich-text.liquid', false],
      ['featured-product.liquid', false],
      ['newsletter.liquid (Klaviyo hook)', false],
      ['image-banner.liquid', false],
    ],
    'Snippets': [
      ['product-card.liquid', true],
      ['cart-drawer.liquid', true],
      ['price.liquid', true],
      ['tag-pill.liquid', true],
      ['quantity-selector.liquid', true],
      ['icon.liquid + icons.svg', true],
      ['image.liquid (responsive wrapper)', false],
    ],
    'Templates': [
      ['index.json', true],
      ['collection.json', true],
      ['product.json', true],
      ['page.json', false],
      ['404.json', false],
      ['password.json (drop teaser)', false],
    ],
    'QA': [
      ['Mobile PDP sticky ATC bar', false],
      ['Cart drawer spring animation', true],
      ['Async add-to-cart (no reload)', true],
      ['Countdown timer (hides at 0)', true],
      ['Lookbook CSS scroll-driven parallax + static fallback', false],
      ['Theme editor: all settings visible and working', false],
      ['Shopify Markets: locale + currency switcher', false],
      ['Accessibility: skip link, focus-visible, ARIA cart count', false],
    ],
  };

  return (
    <Sub no="5.4" title="Build checklist">
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:S[5] }}>
        {Object.entries(items).map(([group, checks]) => (
          <div key={group} style={{ border:`1px solid ${T.ink}`, background:T.paper }}>
            <div className="mono" style={{
              padding:`${S[2]}px ${S[4]}px`, background:T.bone2,
              borderBottom:`1px solid ${T.ink}`, fontSize:10, letterSpacing:'.18em', textTransform:'uppercase',
            }}>{group}</div>
            {checks.map(([label, done], i) => (
              <div key={i} style={{
                display:'flex', alignItems:'center', gap:S[3], padding:`${S[2]}px ${S[4]}px`,
                borderBottom: i < checks.length-1 ? `1px solid ${T.n100}` : 'none',
              }}>
                <span style={{ color: done ? T.positive : T.n300, fontSize:14, lineHeight:1 }}>
                  {done ? '✓' : '○'}
                </span>
                <span style={{ fontSize:13, color: done ? T.ink : T.n400, textDecoration: done ? 'none' : 'none' }}>
                  {label}
                </span>
              </div>
            ))}
          </div>
        ))}
      </div>
      <DevNote>↳ ✓ = critical-path items · ○ = next sprint · update this checklist as work progresses</DevNote>
    </Sub>
  );
};

const CSSUtilitiesSection = () => {
  const CSSBlock = ({ title, children }) => (
    <div style={{ marginBottom:S[4] }}>
      <div className="mono" style={{ fontSize:10, letterSpacing:'.18em', color:T.neon, marginBottom:S[2], textTransform:'uppercase' }}>{title}</div>
      <pre style={{
        background:T.ink, color:'#cfcdc8', padding:S[5],
        fontSize:11, lineHeight:1.75, overflow:'auto', margin:0,
        fontFamily:"'JetBrains Mono', monospace", border:`1px solid ${T.ink}`,
      }}><code>{children}</code></pre>
    </div>
  );

  return (
    <Sub no="5.5" title="CSS utilities → glose.css">
      <div style={{ marginBottom:S[4], padding:S[4], background:T.bone2, border:`1px solid ${T.n200}` }}>
        <span className="mono" style={{ fontSize:10, letterSpacing:'.14em', textTransform:'uppercase', color:T.n500 }}>
          Source: styles.css (earlier prototype) · normalized to final DS token names below
        </span>
      </div>

      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:S[5] }}>
        <div>
          <CSSBlock title="Texture backgrounds">
{`/* Foil / chrome-specular surface */
.foil-bg {
  background:
    radial-gradient(1200px 600px at 20% 30%,
      #f0eee9 0%, transparent 60%),
    radial-gradient(800px 600px at 90% 70%,
      var(--color-chrome) 0%, transparent 55%),
    linear-gradient(135deg,
      #d8d6d2 0%, #a8a6a2 35%,
      #e2e0dc 55%, #b0aea9 75%,
      #cecbc6 100%);
  position: relative;
}
.foil-bg::after {
  content: "";
  position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(115deg,
      rgba(255,255,255,.06) 0 1px,
      transparent 1px 3px),
    repeating-linear-gradient(75deg,
      rgba(0,0,0,.04) 0 1px,
      transparent 1px 4px);
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* Brushed chrome — vertical grain */
.chrome-bg {
  background: linear-gradient(180deg,
    #e6e4e0 0%, #c8c6c2 30%,
    #9c9a96 50%, #cfcdc8 70%,
    #a8a6a2 100%);
  position: relative;
}
.chrome-bg::before {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(90deg,
    rgba(255,255,255,.08) 0 2px,
    transparent 2px 7px,
    rgba(0,0,0,.06) 7px 8px,
    transparent 8px 12px);
  mix-blend-mode: soft-light;
  pointer-events: none;
}`}
          </CSSBlock>

          <CSSBlock title="Marquee (announcement bar drop mode)">
{`@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.marquee {
  display: flex;
  gap: var(--space-7); /* 48px */
  white-space: nowrap;
  animation: marquee 32s linear infinite;
  width: max-content;
}
.marquee--fast { animation-duration: 18s; }
.marquee--slow { animation-duration: 60s; }

/* Usage in announcement-bar.liquid:
   {% if section.settings.drop_mode %}
     <div class="marquee">
       <span>{{ section.settings.drop_text }}</span>
       <span aria-hidden>{{ section.settings.drop_text }}</span>
     </div>
   {% endif %}
*/`}
          </CSSBlock>
        </div>

        <div>
          <CSSBlock title="Neon shimmer (wordmark accent, hover moments)">
{`@keyframes neon-shimmer {
  0%, 100% {
    filter: drop-shadow(0 0 0 transparent);
  }
  50% {
    filter: drop-shadow(0 0 6px var(--color-neon));
  }
}
/* Apply to .wordmark__bar on drop-mode pages */
.is-drop-mode .wordmark__bar {
  animation: neon-shimmer 2.4s ease-in-out infinite;
}`}
          </CSSBlock>

          <CSSBlock title="Custom cursor dot (brand moment, optional)">
{`/* Shown on .glose-screen pages only */
.cursor-dot {
  position: fixed;
  pointer-events: none;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--color-neon);
  box-shadow:
    0 0 0 2px #fff,
    0 0 18px var(--color-neon);
  z-index: 50;
  transform: translate(-50%, -50%);
  transition: opacity var(--dur-fast) var(--ease-standard);
}
/* JS: track mousemove, update left/top */`}
          </CSSBlock>

          <CSSBlock title="Placeholder product photo (dev only)">
{`/* Remove before launch — dev placeholder only */
.placeholder-photo {
  position: relative;
  background:
    repeating-linear-gradient(45deg,
      rgba(0,0,0,.04) 0 8px,
      rgba(255,255,255,.04) 8px 16px),
    linear-gradient(160deg,
      #d6d3ce 0%, #aaa7a2 50%,
      #c8c5c0 100%);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.placeholder-photo::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 30% 40%,
      rgba(255,255,255,.4), transparent 40%),
    radial-gradient(circle at 70% 70%,
      rgba(0,0,0,.18), transparent 50%);
  pointer-events: none;
}`}
          </CSSBlock>
        </div>
      </div>
      <DevNote>↳ foil-bg a chrome-bg jsou produkční — použij na hero bg, PDP gallery placeholder, lookbook ink tiles · ostatní jsou volitelné nebo dev-only</DevNote>
    </Sub>
  );
};

const HandoffSection = () => (
  <Section no="05" title="Handoff" kicker="tokens · rules · css utils · checklist">
    <TokenMapSection/>
    <RulesSection/>
    <JSPatternsSection/>
    <CSSUtilitiesSection/>
    <ChecklistSection/>
  </Section>
);

Object.assign(window, { HandoffSection });
