/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

const DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "blue",
  "dark": false
}/*EDITMODE-END*/;

const asset = (path) => {
  if (!path || /^([a-z]+:)?\/\//i.test(path) || path.startsWith("data:") || path.startsWith("#")) return path;
  const base = window.OCEANIS_THEME_URI || "";
  return base ? `${base.replace(/\/$/, "")}/${path.replace(/^\/+/, "")}` : path;
};

const homeUrl = (hash = "") => {
  const base = window.OCEANIS_HOME_URL || "/";
  return `${base.replace(/\/?$/, "/")}${hash}`;
};

const privacyUrl = () => window.OCEANIS_PRIVACY_URL || "privacy.html";

/* ---------- Reveal hook (IntersectionObserver) ---------- */
const useReveal = (opts = {}) => {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setShown(true);
            io.unobserve(el);
          }
        });
      },
      { threshold: opts.threshold ?? 0.15, rootMargin: opts.rootMargin ?? "0px 0px -8% 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, shown];
};

const Reveal = ({ children, delay = 0, y = 24, as: As = "div", className = "", style = {}, ...rest }) => {
  const [ref, shown] = useReveal();
  return (
    <As ref={ref} className={className} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? "none" : `translateY(${y}px)`,
      transition: `opacity 720ms cubic-bezier(.2,.7,.1,1) ${delay}ms, transform 760ms cubic-bezier(.2,.7,.1,1) ${delay}ms`,
      willChange: "opacity, transform",
      ...style,
    }} {...rest}>{children}</As>
  );
};

const LazyImage = ({ src, alt, className = "", eager = false, ...rest }) => (
  <img
    src={asset(src)}
    alt={alt}
    className={className}
    loading={eager ? "eager" : "lazy"}
    decoding="async"
    fetchPriority={eager ? "high" : "low"}
    {...rest}
  />
);

const InlineSvg = ({ src, className = "", play = true, label = "" }) => {
  const [markup, setMarkup] = useState("");

  useEffect(() => {
    let cancelled = false;
    fetch(asset(src))
      .then((res) => res.text())
      .then((text) => {
        if (!cancelled) setMarkup(text);
      })
      .catch(() => {
        if (!cancelled) setMarkup("");
      });
    return () => {
      cancelled = true;
    };
  }, [src]);

  return (
    <div
      className={`${className} ${play ? "is-active" : ""}`.trim()}
      aria-label={label}
      dangerouslySetInnerHTML={{ __html: markup }}
    />
  );
};

const AutoVideo = ({ className = "", src, type = "video/mp4", preload = "auto", ...rest }) => {
  const videoRef = useRef(null);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;
    const playPromise = video.play();
    if (playPromise && typeof playPromise.catch === "function") {
      playPromise.catch(() => {});
    }
  }, [src]);

  return (
    <video ref={videoRef} className={className} autoPlay muted loop playsInline preload={preload} {...rest}>
      <source src={asset(src)} type={type} />
    </video>
  );
};

/* ---------- icon helpers ---------- */
const Icon = ({ name, size = 18, stroke = 1.6 }) => {
  const s = { width: size, height: size, fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "chev":      return <svg {...s} viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg>;
    case "arrow":     return <svg {...s} viewBox="0 0 24 24"><path d="M5 12h14"/><path d="M13 5l7 7-7 7"/></svg>;
    case "arrow-ne":  return <svg {...s} viewBox="0 0 24 24"><path d="M7 17L17 7"/><path d="M9 7h8v8"/></svg>;
    case "tag":       return <svg {...s} viewBox="0 0 24 24"><path d="M20 12V4h-8L3 13l8 8 9-9z"/><circle cx="15" cy="9" r="1.5" fill="currentColor"/></svg>;
    case "quote":     return <svg {...s} viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M7 7h4v4H8c0 2 1 3 3 3v3c-3 0-5-2-5-5V7zm9 0h4v4h-3c0 2 1 3 3 3v3c-3 0-5-2-5-5V7z"/></svg>;
    default: return null;
  }
};

/* ---------- Nav ---------- */
const Nav = () => (
  <div className="nav-wrap">
    <nav className="nav">
      <a href={homeUrl()} className="nav-brand">
        <LazyImage src="assets/images/logos/oceanis-logo-website.png" alt="Oceanis" eager={true} />
      </a>
      <div className="nav-links">
        <a href={homeUrl("#services")}>Services</a>
        <a href={homeUrl("#network")}>Network</a>
        <a href={homeUrl("#approach")}>About</a>
      </div>
      <div className="nav-spacer"></div>
      <a href={homeUrl("#contact")} className="nav-cta">
        <span className="dot"></span>
        Get in touch
      </a>
    </nav>
  </div>
);

/* ---------- Hero ---------- */
const Hero = () => (
  <section className="hero">
    <div className="hero-card">
      <div className="hero-img-slot">
        <AutoVideo
          className="hero-video"
          src="assets/media/videos/hero/hero-section-vessel-low-20260624.mp4"
          preload="auto"
          aria-hidden="true"
        />
      </div>
      <div className="hero-scrim" aria-hidden="true"></div>
      <div className="hero-content">
        <h1 className="anim-in" style={{animationDelay: "160ms"}}>
          Trade <em>flows</em><br/>where Oceanis delivers
        </h1>
        <p className="hero-sub anim-in" style={{animationDelay: "340ms"}}>
          Reliable bulk, dry-bulk and container shipping and logistics solutions across Asia, the Middle East, Africa and the Indian Subcontinent.
        </p>
        <div className="hero-spacer"></div>
      </div>
    </div>
  </section>
);

/* ---------- Bento charts (animated) ---------- */
const BarsViz = ({ play }) => {
  // Reliable capacity — wave of bars rising in
  const N = 32;
  return (
    <svg viewBox="0 0 320 100" preserveAspectRatio="none" style={{width:"100%", height:"100%", display:"block"}}>
      <defs>
        <linearGradient id="bv-1" x1="0" x2="1">
          <stop offset="0" stopColor="#02ADEE"/>
          <stop offset="1" stopColor="#77C04B"/>
        </linearGradient>
      </defs>
      {Array.from({length: N}).map((_, i) => {
        const h = 30 + Math.sin(i * 0.7) * 20 + Math.cos(i * 0.3) * 14 + 30;
        const delay = i * 35;
        return (
          <rect key={i}
            x={i*10} y={100-h} width="6" height={h}
            fill="url(#bv-1)" opacity={play ? (0.7 + (i%3)*0.1) : 0}
            style={{
              transformOrigin: `${i*10 + 3}px 100px`,
              transform: play ? "scaleY(1)" : "scaleY(0)",
              transition: `transform 800ms cubic-bezier(.2,.8,.2,1) ${delay}ms, opacity 400ms ${delay}ms`,
            }}
          />
        );
      })}
    </svg>
  );
};

const PricingViz = ({ play }) => {
  const data = [28, 36, 52, 44, 64, 56, 72, 60, 84, 70, 92];
  return (
    <div style={{display:"flex", alignItems:"flex-end", gap: 6, height: "100%", width: "100%"}}>
      {data.map((h, i) => (
        <div key={i} style={{
          flex: 1,
          height: play ? `${h}%` : "0%",
          background: "linear-gradient(180deg, #02ADEE, #77C04B)",
          borderRadius: 3,
          opacity: 0.9,
          transition: `height 900ms cubic-bezier(.2,.8,.2,1) ${i*70}ms`,
        }}/>
      ))}
    </div>
  );
};

const ServiceOrbitsViz = ({ play }) => (
  <svg viewBox="0 0 160 110" style={{width:"100%", height:"100%"}}>
    <defs>
      <radialGradient id="ov-glow">
        <stop offset="0" stopColor="#1F7A8C" stopOpacity="0.45"/>
        <stop offset="1" stopColor="#1F7A8C" stopOpacity="0"/>
      </radialGradient>
    </defs>
    <circle cx="80" cy="55" r="36" fill="none" stroke="#1F7A8C" strokeWidth="1" opacity="0.35"
      strokeDasharray="3 6"
      style={{
        transformOrigin: "80px 55px",
        animation: play ? "spin-slow 22s linear infinite" : "none",
      }}/>
    <circle cx="80" cy="55" r="22" fill="none" stroke="#1F7A8C" strokeWidth="1" opacity="0.55"
      strokeDasharray="2 4"
      style={{
        transformOrigin: "80px 55px",
        animation: play ? "spin-rev 16s linear infinite" : "none",
      }}/>
    <circle cx="80" cy="55" r="44" fill="url(#ov-glow)"/>
    <circle cx="80" cy="55" r="8" fill="#1F7A8C"/>
    {[0, 72, 144, 216, 288].map((deg, i) => {
      const r = i % 2 === 0 ? 36 : 22;
      const x = 80 + Math.cos((deg - 90) * Math.PI / 180) * r;
      const y = 55 + Math.sin((deg - 90) * Math.PI / 180) * r;
      const c = i % 2 === 0 ? "#02ADEE" : "#77C04B";
      return (
        <circle key={i} cx={x} cy={y} r="3.5" fill={c}
          style={{
            opacity: play ? 1 : 0,
            transition: `opacity 500ms ${300 + i*100}ms`,
          }}/>
      );
    })}
  </svg>
);

const WaveViz = ({ play }) => (
  <svg viewBox="0 0 160 80" style={{width:"100%", height:"100%"}}>
    <path d="M5 40 Q 30 8, 60 40 T 115 40 T 155 40"
          fill="none" stroke="white" strokeWidth="1.8"
          strokeDasharray="400"
          strokeDashoffset={play ? 0 : 400}
          style={{transition: "stroke-dashoffset 1600ms cubic-bezier(.2,.8,.2,1)"}}/>
    <circle cx="5" cy="40" r="4" fill="white" style={{opacity: play ? 1 : 0, transition: "opacity 400ms 200ms"}}/>
    <circle cx="60" cy="40" r="4" fill="white" style={{opacity: play ? 1 : 0, transition: "opacity 400ms 800ms"}}/>
    <circle cx="115" cy="40" r="4" fill="white" style={{opacity: play ? 1 : 0, transition: "opacity 400ms 1200ms"}}/>
    <circle cx="155" cy="40" r="4" fill="white" style={{opacity: play ? 1 : 0, transition: "opacity 400ms 1500ms"}}/>
  </svg>
);

const CompetitiveBarsViz = ({ play }) => {
  const bars = [
    { x: 8, base: 102, h1: 26, h2: 22 },
    { x: 50, base: 102, h1: 38, h2: 28 },
    { x: 92, base: 102, h1: 56, h2: 36 },
    { x: 134, base: 102, h1: 68, h2: 44 },
    { x: 176, base: 102, h1: 84, h2: 52 },
    { x: 218, base: 102, h1: 118, h2: 66 },
  ];
  return (
    <svg viewBox="0 0 260 122" style={{width:"100%", height:"100%", display:"block"}}>
      <defs>
        <linearGradient id="pricing-bar-top" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor="#ffffff"/>
          <stop offset="1" stopColor="#2ad4a1"/>
        </linearGradient>
        <linearGradient id="pricing-bar-bottom" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor="#ffffff"/>
          <stop offset="1" stopColor="#217aff"/>
        </linearGradient>
      </defs>
      {bars.map((bar, i) => (
        <g key={bar.x} style={{ transform: `translateY(${play ? 0 : 18}px)`, opacity: play ? 1 : 0, transition: `transform 700ms cubic-bezier(.2,.8,.2,1) ${i * 70}ms, opacity 450ms ${i * 70}ms` }}>
          <rect
            x={bar.x}
            y={bar.base - bar.h1}
            width="28"
            height={bar.h1}
            rx="2"
            fill="url(#pricing-bar-top)"
            style={{
              transformOrigin: `${bar.x + 14}px ${bar.base}px`,
              transform: play ? "scaleY(1)" : "scaleY(0.05)",
              transition: `transform 900ms cubic-bezier(.2,.8,.2,1) ${i * 90}ms`
            }}
          />
          <rect
            x={bar.x}
            y={bar.base - bar.h1 - bar.h2}
            width="28"
            height={bar.h2}
            rx="2"
            fill="url(#pricing-bar-bottom)"
            style={{
              transformOrigin: `${bar.x + 14}px ${bar.base - bar.h1}px`,
              transform: play ? "scaleY(1)" : "scaleY(0.05)",
              transition: `transform 950ms cubic-bezier(.2,.8,.2,1) ${150 + i * 90}ms`
            }}
          />
        </g>
      ))}
    </svg>
  );
};

const ServiceNetworkViz = ({ play }) => {
  const nodes = [
    { x: 130, y: 22, c: "#2ad4a1" },
    { x: 58, y: 52, c: "#217aff" },
    { x: 202, y: 52, c: "#2ad4a1" },
    { x: 88, y: 102, c: "#2ad4a1" },
    { x: 172, y: 102, c: "#217aff" },
    { x: 130, y: 68, c: "#217aff", r: 10 }
  ];
  const links = [
    [0, 5], [1, 5], [2, 5], [3, 5], [4, 5], [1, 3], [2, 4]
  ];
  return (
    <svg viewBox="0 0 260 122" style={{width:"100%", height:"100%", display:"block"}}>
      {links.map(([a, b], i) => (
        <line
          key={`${a}-${b}`}
          x1={nodes[a].x}
          y1={nodes[a].y}
          x2={nodes[b].x}
          y2={nodes[b].y}
          stroke="rgba(31,122,140,0.45)"
          strokeWidth="2"
          strokeDasharray="6 6"
          style={{
            strokeDashoffset: play ? -24 : 0,
            opacity: play ? 1 : 0.2,
            transition: `opacity 500ms ${i * 70}ms`,
            animation: play ? "line-march 1.4s linear infinite" : "none"
          }}
        />
      ))}
      {nodes.map((node, i) => (
        <g key={`${node.x}-${node.y}`} style={{ transformOrigin: `${node.x}px ${node.y}px` }}>
          <circle
            cx={node.x}
            cy={node.y}
            r={(node.r ?? 6) + 6}
            fill={node.c}
            opacity="0.12"
            style={{ animation: play ? `glow-pulse ${2.4 + i * 0.15}s ease-in-out infinite` : "none" }}
          />
          <circle
            cx={node.x}
            cy={node.y}
            r={node.r ?? 6}
            fill={node.c}
            style={{
              transform: play ? "scale(1)" : "scale(0.2)",
              opacity: play ? 1 : 0,
              transition: `transform 650ms cubic-bezier(.2,.8,.2,1) ${180 + i * 80}ms, opacity 400ms ${180 + i * 80}ms`
            }}
          />
        </g>
      ))}
    </svg>
  );
};

const Bento = () => {
  const [ref1, shown1] = useReveal();
  const [ref2, shown2] = useReveal();
  const [ref3, shown3] = useReveal();
  const [ref4, shown4] = useReveal();
  return (
  <section className="section" id="approach">
    <div className="container">
      <Reveal className="section-head">
        <div className="left">
          <h2>Solutions built around the realities of regional trade.</h2>
          <p className="desc">A dedicated liner network across the Indian Ocean, offering reliable schedules, agile service and deep regional market knowledge.</p>
        </div>
        <a href={homeUrl("#services")} className="section-link">See services <Icon name="arrow" size={14}/></a>
      </Reveal>

      <div className="bento">
        <div className="card card-1" ref={ref1}>
          <div className="card-bg-media" aria-hidden="true">
            <LazyImage src="assets/images/why-us/reliable-capacity.png" alt="" />
          </div>
          <div className="eyebrow">Assured capacity</div>
          <h3>Capacity you can count on, lane after lane.</h3>
          <p className="body">Carefully managed vessel deployment, strong partner networks and well-structured service schedules, so your cargo moves on time, every time. Capacity backed by vessels and slot agreements with mainline carriers.</p>
        </div>

        <div className="card card-2" ref={ref2}>
          <div className="eyebrow">Competitive pricing</div>
          <h3>Cost-efficient by design.</h3>
          <p className="body">Operational efficiencies, strategic alliances and flexible commercial structures. Delivering freight competitively without compromising on service quality.</p>
          <InlineSvg src="assets/graphics/bar-chart-ascending-animated.svg?v=20260514-1530" className="viz viz-svg-file viz-bars" label="Competitive pricing chart" />
        </div>

        <div className="card card-3" ref={ref3}>
          <div className="eyebrow">Personalised service</div>
          <h3>Tailored to your needs</h3>
          <p className="body">Dedicated support and flexible handling for every shipment, relationship-driven, not transactional.</p>
          <InlineSvg src="assets/graphics/why-us-section-network-animated.svg?v=20260514-1530" className="viz viz-svg-file viz-network" label="Personalised service network graphic" />
        </div>

        <div className="card card-4" ref={ref4}>
          <div className="card-bg-media" aria-hidden="true">
            <LazyImage src="assets/images/why-us/trade-lane-focus.png" alt="" />
          </div>
          <div className="eyebrow">Trade-lane focus</div>
          <h3>Depth over breadth.</h3>
          <p className="body">A select network of high-potential lanes. Deeper market understanding and better schedule integrity.</p>
        </div>
      </div>
    </div>
  </section>
  );
};

/* ---------- Service illustrations ---------- */
const SvcContainer = () => (
  <svg viewBox="0 0 200 140" className="svc-art">
    <defs>
      <linearGradient id="svc1-sea" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0" stopColor="#02ADEE" stopOpacity="0.25"/>
        <stop offset="1" stopColor="#02ADEE" stopOpacity="0.05"/>
      </linearGradient>
      <linearGradient id="svc1-c" x1="0" x2="1">
        <stop offset="0" stopColor="#02ADEE"/>
        <stop offset="1" stopColor="#77C04B"/>
      </linearGradient>
    </defs>
    {/* containers stacked */}
    <g className="svc1-stack">
      <rect x="30" y="80" width="36" height="22" rx="2" fill="url(#svc1-c)"/>
      <rect x="68" y="80" width="36" height="22" rx="2" fill="#1F7A8C" opacity="0.85"/>
      <rect x="106" y="80" width="36" height="22" rx="2" fill="url(#svc1-c)" opacity="0.85"/>
      <rect x="49" y="56" width="36" height="22" rx="2" fill="#1F7A8C"/>
      <rect x="87" y="56" width="36" height="22" rx="2" fill="url(#svc1-c)"/>
      <rect x="68" y="32" width="36" height="22" rx="2" fill="url(#svc1-c)" opacity="0.9"/>
    </g>
    {/* container detail lines */}
    <g stroke="rgba(255,255,255,0.35)" strokeWidth="0.6" fill="none">
      {[30,68,106].map((x,i) => <g key={i}><line x1={x+4} y1="84" x2={x+4} y2="98"/><line x1={x+10} y1="84" x2={x+10} y2="98"/><line x1={x+16} y1="84" x2={x+16} y2="98"/><line x1={x+22} y1="84" x2={x+22} y2="98"/><line x1={x+28} y1="84" x2={x+28} y2="98"/></g>)}
    </g>
    {/* ocean waves */}
    <path d="M0 110 Q 25 102 50 110 T 100 110 T 150 110 T 200 110 L 200 140 L 0 140 Z" fill="url(#svc1-sea)" className="svc1-wave"/>
    <path d="M0 118 Q 25 112 50 118 T 100 118 T 150 118 T 200 118" fill="none" stroke="#02ADEE" strokeWidth="1" opacity="0.4" className="svc1-wave2"/>
  </svg>
);

const SvcVessel = () => (
  <svg viewBox="0 0 200 140" className="svc-art">
    <defs>
      <linearGradient id="svc2-h" x1="0" x2="1">
        <stop offset="0" stopColor="#0B1F33"/>
        <stop offset="1" stopColor="#1F7A8C"/>
      </linearGradient>
    </defs>
    {/* radar arcs */}
    <g className="svc2-radar" style={{transformOrigin: "100px 80px"}}>
      <circle cx="100" cy="80" r="28" fill="none" stroke="#02ADEE" strokeWidth="0.8" opacity="0.4"/>
      <circle cx="100" cy="80" r="44" fill="none" stroke="#02ADEE" strokeWidth="0.6" opacity="0.3"/>
      <circle cx="100" cy="80" r="60" fill="none" stroke="#02ADEE" strokeWidth="0.5" opacity="0.2"/>
    </g>
    <g className="svc2-sweep" style={{transformOrigin: "100px 80px"}}>
      <path d="M100 80 L 100 20 A 60 60 0 0 1 152 110 Z" fill="#02ADEE" opacity="0.12"/>
    </g>
    {/* ship */}
    <g transform="translate(60 70)">
      <path d="M0 22 L 80 22 L 72 38 L 8 38 Z" fill="url(#svc2-h)"/>
      <rect x="18" y="6" width="44" height="16" fill="#fff" opacity="0.95"/>
      <rect x="22" y="9" width="6" height="5" fill="#02ADEE" opacity="0.7"/>
      <rect x="32" y="9" width="6" height="5" fill="#02ADEE" opacity="0.7"/>
      <rect x="42" y="9" width="6" height="5" fill="#02ADEE" opacity="0.7"/>
      <rect x="52" y="9" width="6" height="5" fill="#02ADEE" opacity="0.7"/>
      <rect x="34" y="-8" width="3" height="14" fill="#0B1F33"/>
      <rect x="44" y="-12" width="3" height="18" fill="#0B1F33"/>
    </g>
    {/* status dots */}
    <circle cx="40" cy="30" r="3" fill="#77C04B" className="svc2-dot"/>
    <circle cx="160" cy="40" r="3" fill="#02ADEE" className="svc2-dot" style={{animationDelay: "300ms"}}/>
    <circle cx="170" cy="110" r="3" fill="#77C04B" className="svc2-dot" style={{animationDelay: "600ms"}}/>
  </svg>
);

const SvcRoute = () => (
  <svg viewBox="0 0 200 140" className="svc-art">
    <defs>
      <linearGradient id="svc3-r" x1="0" x2="1">
        <stop offset="0" stopColor="#02ADEE"/>
        <stop offset="1" stopColor="#77C04B"/>
      </linearGradient>
    </defs>
    {/* dotted grid backdrop */}
    {Array.from({length:6}).map((_,i) => <line key={i} x1="0" y1={i*24+10} x2="200" y2={i*24+10} stroke="rgba(31,122,140,0.15)" strokeWidth="0.5" strokeDasharray="2 4"/>)}
    {/* warehouse left */}
    <g transform="translate(14 70)">
      <rect x="0" y="14" width="32" height="22" fill="#1F7A8C" opacity="0.85"/>
      <path d="M0 14 L 16 0 L 32 14 Z" fill="#0B1F33"/>
      <rect x="12" y="22" width="8" height="14" fill="#fff" opacity="0.5"/>
    </g>
    {/* truck middle */}
    <g transform="translate(80 78)" className="svc3-truck">
      <rect x="0" y="6" width="22" height="14" rx="1" fill="#02ADEE"/>
      <rect x="22" y="2" width="14" height="18" rx="1" fill="#0B1F33"/>
      <rect x="25" y="5" width="8" height="6" fill="#fff" opacity="0.8"/>
      <circle cx="6" cy="22" r="3" fill="#0B1F33"/>
      <circle cx="18" cy="22" r="3" fill="#0B1F33"/>
      <circle cx="30" cy="22" r="3" fill="#0B1F33"/>
    </g>
    {/* destination right */}
    <g transform="translate(160 70)">
      <rect x="0" y="14" width="26" height="22" fill="#77C04B" opacity="0.85"/>
      <path d="M0 14 L 13 0 L 26 14 Z" fill="#0B1F33"/>
      <rect x="10" y="24" width="6" height="12" fill="#fff" opacity="0.5"/>
    </g>
    {/* route line */}
    <path d="M 30 70 Q 100 30, 170 70" fill="none" stroke="url(#svc3-r)" strokeWidth="2" strokeDasharray="3 4" className="svc3-line"/>
    <circle r="4" fill="#fff" stroke="#02ADEE" strokeWidth="1.5">
      <animateMotion dur="4s" repeatCount="indefinite" path="M 30 70 Q 100 30, 170 70"/>
    </circle>
  </svg>
);

const SvcCharter = () => (
  <svg viewBox="0 0 200 140" className="svc-art">
    <defs>
      <linearGradient id="svc4-c" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0" stopColor="#02ADEE"/>
        <stop offset="1" stopColor="#1F7A8C"/>
      </linearGradient>
      <linearGradient id="svc4-c2" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0" stopColor="#77C04B"/>
        <stop offset="1" stopColor="#4FAE82"/>
      </linearGradient>
    </defs>
    {/* horizon */}
    <line x1="0" y1="60" x2="200" y2="60" stroke="rgba(2,173,238,0.25)" strokeDasharray="2 4"/>
    {/* document tiles */}
    <g className="svc4-doc">
      <rect x="20" y="22" width="44" height="58" rx="3" fill="url(#svc4-c)" opacity="0.85"/>
      <rect x="26" y="32" width="32" height="2" fill="#fff" opacity="0.6"/>
      <rect x="26" y="38" width="24" height="2" fill="#fff" opacity="0.5"/>
      <rect x="26" y="44" width="28" height="2" fill="#fff" opacity="0.5"/>
      <rect x="26" y="60" width="14" height="14" fill="#fff" opacity="0.85"/>
      <path d="M28 67 l3 3 l6 -7" stroke="#02ADEE" strokeWidth="2" fill="none"/>
    </g>
    <g className="svc4-doc" style={{transform: "translate(72px, 0)"}}>
      <rect x="20" y="32" width="44" height="58" rx="3" fill="url(#svc4-c2)" opacity="0.85"/>
      <rect x="26" y="42" width="32" height="2" fill="#fff" opacity="0.6"/>
      <rect x="26" y="48" width="24" height="2" fill="#fff" opacity="0.5"/>
      <rect x="26" y="54" width="28" height="2" fill="#fff" opacity="0.5"/>
      <rect x="26" y="70" width="14" height="14" fill="#fff" opacity="0.85"/>
      <path d="M28 77 l3 3 l6 -7" stroke="#77C04B" strokeWidth="2" fill="none"/>
    </g>
    {/* clock badge */}
    <g transform="translate(150 56)" className="svc4-clock">
      <circle r="18" fill="#0B1F33"/>
      <circle r="14" fill="none" stroke="rgba(255,255,255,0.2)" strokeWidth="1"/>
      <line x1="0" y1="0" x2="0" y2="-10" stroke="#02ADEE" strokeWidth="2" strokeLinecap="round" className="svc4-hand"/>
      <line x1="0" y1="0" x2="8" y2="0" stroke="#77C04B" strokeWidth="1.8" strokeLinecap="round" className="svc4-hand-2"/>
      <circle r="2" fill="#fff"/>
    </g>
  </svg>
);

const SERVICES = [
  {
    title: "Sea Cargo Services",
    body: "Full Container Load (FCL) and Less than Container Load (LCL) cargo with space secured through our vessels plus slot and space arrangements with mainline carriers via vessel sharing agreements (VSA) and slot sharing agreements (SCA).",
    tags: ["FCL", "LCL", "VSA", "SCA"],
    layout: "service-card detail-card",
    kicker: "Core lane access",
    video: "assets/media/videos/services/sea-cargo-services-low-20260624.mp4"
  },
  {
    title: "Logistics & Transportation",
    body: "Logistics and transportation coordination and multimodal transport delivered through trusted regional partners across our core corridors.",
    tags: ["Inland haulage", "Multimodal"],
    layout: "service-card detail-card",
    kicker: "Connected delivery",
    video: "assets/media/videos/services/logistics-and-transportation-low-20260624.mp4"
  },
  {
    title: "Ship Chartering",
    body: "Short-term and contractual chartering solutions for cargo and seasonal demand, flexible tonnage when and where you need it.",
    tags: ["Project cargo", "Seasonal", "Spot & contract"],
    layout: "service-card detail-card",
    kicker: "Flexible tonnage",
    video: "assets/media/videos/services/ship-chartering-low-20260624.mp4"
  },
];

const Services = () => (
  <section className="services-section" id="services">
    <div className="container">
      <Reveal className="section-head services-head">
        <div className="left">
          <h2>End-to-end freight solutions.</h2>
          <p className="desc">Solutions designed to move cargo across the supply chain.</p>
        </div>
        <a href={homeUrl("#contact")} className="section-link">Get in touch <Icon name="arrow" size={14}/></a>
      </Reveal>

      <div className="services-grid">
        {SERVICES.map((s, i) => (
          <Reveal key={s.title} delay={i * 80} className={s.layout}>
            <div className="svc-body svc-body-dark">
              <div className="svc-meta">
                <div className="svc-kicker">{s.kicker}</div>
              </div>
              <h3>{s.title}</h3>
              <p className="body">{s.body}</p>
              <div className="tags">
                {s.tags.map((t) => <span className="tag" key={t}>{t}</span>)}
              </div>
              <div className="svc-video-box svc-video-box-inline has-video" aria-label={`${s.title} video`}>
                <AutoVideo className="svc-video" src={s.video} preload="metadata" aria-hidden="true" />
              </div>
            </div>
          </Reveal>
        ))}
      </div>
    </div>
  </section>
);

/* ---------- World Map (regional glow) ---------- */
/* Schematic continent paths sized to a 1000x500 viewBox.
   Regional dots are simplified geo positions. */
const WorldMap = () => (
  <div className="world-wrap">
    <LazyImage src="assets/images/maps/oceanis-website-map.svg" alt="Oceanis regional coverage map" className="world-map-base" />
    <div className="region-legend">
      <div className="region-chip"><span className="chip-dot" style={{background: "#b2ffdb"}}></span>Southeast Asia</div>
      <div className="region-chip"><span className="chip-dot" style={{background: "#b2b9ff"}}></span>South Asia</div>
      <div className="region-chip"><span className="chip-dot" style={{background: "#bec5e0"}}></span>China</div>
      <div className="region-chip"><span className="chip-dot" style={{background: "#93c0d1"}}></span>Middle East</div>
      <div className="region-chip"><span className="chip-dot" style={{background: "#89deff"}}></span>East Africa</div>
    </div>
  </div>
);

const Coverage = () => (
  <section className="coverage" id="network">
    <div className="container">
      <Reveal className="coverage-head">
        <h2><span className="coverage-line">One ocean. Five regions.</span><br/><em>Every link in the chain.</em></h2>
        <p className="body">Operating across Africa, China, Southeast Asia, South Asia and the Middle East — the high-potential corridors at the heart of Indian Ocean trade.</p>
      </Reveal>
      <Reveal delay={120}>
        <div className="coverage-card">
          <WorldMap/>
        </div>
      </Reveal>
    </div>
  </section>
);

/* ---------- Vision & Mission — editorial split ---------- */
const CompassViz = () => (
  <svg viewBox="0 0 300 300" className="compass-svg" aria-hidden="true">
    <defs>
      <linearGradient id="cmp-g" x1="0" y1="0" x2="1" y2="1">
        <stop offset="0" stopColor="#6FD7FF"/>
        <stop offset="1" stopColor="#A4E27A"/>
      </linearGradient>
      <radialGradient id="cmp-glow">
        <stop offset="0" stopColor="#6FD7FF" stopOpacity="0.45"/>
        <stop offset="1" stopColor="#6FD7FF" stopOpacity="0"/>
      </radialGradient>
    </defs>
    <circle cx="150" cy="150" r="140" fill="url(#cmp-glow)"/>
    {/* outer ring with tick marks */}
    <g className="compass-ring" style={{transformOrigin: "150px 150px"}}>
      <circle cx="150" cy="150" r="128" fill="none" stroke="rgba(255,255,255,0.4)" strokeWidth="1"/>
      {Array.from({length: 72}).map((_, i) => {
        const a = (i * 5 - 90) * Math.PI / 180;
        const r1 = i % 6 === 0 ? 116 : 122;
        const r2 = 128;
        const x1 = 150 + Math.cos(a) * r1, y1 = 150 + Math.sin(a) * r1;
        const x2 = 150 + Math.cos(a) * r2, y2 = 150 + Math.sin(a) * r2;
        return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="rgba(255,255,255,0.55)" strokeWidth={i % 6 === 0 ? 1.4 : 0.6}/>;
      })}
      <text x="150" y="100" textAnchor="middle" fontFamily="Montserrat" fontWeight="700" fontSize="14" fill="#fff">N</text>
      <text x="200" y="155" textAnchor="middle" fontFamily="Montserrat" fontWeight="700" fontSize="14" fill="rgba(255,255,255,0.6)">E</text>
      <text x="150" y="210" textAnchor="middle" fontFamily="Montserrat" fontWeight="700" fontSize="14" fill="rgba(255,255,255,0.6)">S</text>
      <text x="100" y="155" textAnchor="middle" fontFamily="Montserrat" fontWeight="700" fontSize="14" fill="rgba(255,255,255,0.6)">W</text>
    </g>
    {/* mid ring */}
    <circle cx="150" cy="150" r="96" fill="none" stroke="rgba(255,255,255,0.18)" strokeWidth="1" strokeDasharray="2 4" className="compass-mid" style={{transformOrigin: "150px 150px"}}/>
    {/* needle */}
    <g className="compass-needle" style={{transformOrigin: "150px 150px"}}>
      <path d="M 150 60 L 162 150 L 150 162 L 138 150 Z" fill="url(#cmp-g)"/>
      <path d="M 150 240 L 162 150 L 150 138 L 138 150 Z" fill="rgba(255,255,255,0.18)"/>
    </g>
    <circle cx="150" cy="150" r="6" fill="#fff"/>
    <circle cx="150" cy="150" r="14" fill="none" stroke="#fff" opacity="0.4"/>
  </svg>
);

const FlowViz = () => (
  <svg viewBox="0 0 400 300" className="flow-svg" aria-hidden="true">
    <defs>
      <linearGradient id="flw-g" x1="0" x2="1">
        <stop offset="0" stopColor="#A4E27A"/>
        <stop offset="1" stopColor="#6FD7FF"/>
      </linearGradient>
      <radialGradient id="flw-node">
        <stop offset="0" stopColor="#fff" stopOpacity="1"/>
        <stop offset="1" stopColor="#fff" stopOpacity="0.2"/>
      </radialGradient>
    </defs>
    {/* flowing band */}
    <path d="M 0 220 Q 80 140, 160 180 T 320 140 T 400 110" fill="none" stroke="url(#flw-g)" strokeWidth="2.5" strokeLinecap="round" className="flow-line"/>
    <path d="M 0 240 Q 80 165, 160 205 T 320 170 T 400 140" fill="none" stroke="url(#flw-g)" strokeWidth="1.5" strokeLinecap="round" opacity="0.55" className="flow-line" style={{animationDelay: "-1.5s"}}/>
    <path d="M 0 260 Q 80 190, 160 230 T 320 200 T 400 170" fill="none" stroke="url(#flw-g)" strokeWidth="1" strokeLinecap="round" opacity="0.3" className="flow-line" style={{animationDelay: "-3s"}}/>
    {/* nodes */}
    {[
      {x: 40,  y: 215, lbl: "CN"},
      {x: 130, y: 165, lbl: "SE"},
      {x: 215, y: 175, lbl: "SA"},
      {x: 300, y: 145, lbl: "ME"},
      {x: 370, y: 115, lbl: "AF"},
    ].map((n, i) => (
      <g key={n.lbl}>
        <circle cx={n.x} cy={n.y} r="18" fill="url(#flw-node)" opacity="0.25" className="flow-node-halo" style={{animationDelay: `${i*300}ms`}}/>
        <circle cx={n.x} cy={n.y} r="8" fill="#fff"/>
        <text x={n.x} y={n.y + 4} textAnchor="middle" fontFamily="Montserrat" fontWeight="700" fontSize="8" fill="#0B1F33">{n.lbl}</text>
      </g>
    ))}
    {/* moving cargo dot */}
    <circle r="5" fill="#A4E27A">
      <animateMotion dur="6s" repeatCount="indefinite" path="M 0 220 Q 80 140, 160 180 T 320 140 T 400 110"/>
    </circle>
    <circle r="10" fill="none" stroke="#A4E27A" opacity="0.5">
      <animateMotion dur="6s" repeatCount="indefinite" path="M 0 220 Q 80 140, 160 180 T 320 140 T 400 110"/>
    </circle>
  </svg>
);

const Approach = () => (
  <section className="approach">
    <div className="container">
      <Reveal className="approach-head">
        <h2>What guides every <em>mile</em>.</h2>
      </Reveal>

      <div className="approach-grid-v2">
        <Reveal className="approach-card-v2 vision">
          <div className="approach-text">
            <div className="approach-marker-v2">
              <span className="marker-lbl">Vision</span>
            </div>
            <h3 className="approach-quote">
              To be a <em>regional Indian Ocean<br/>trade facilitator</em> connecting fast-growing trade corridors of Asia and Africa.
            </h3>
          </div>
        </Reveal>

        <Reveal delay={140} className="approach-card-v2 mission">
          <div className="approach-text">
            <div className="approach-marker-v2">
              <span className="marker-lbl">Mission</span>
            </div>
            <h3 className="approach-quote">
              To provide reliable and streamlined maritime transport solutions across major trade corridors linking <em>China, Southeast Asia, South Asia, the Middle East and Africa.</em> With a strong customer-first approach, the company focuses on enabling smooth cargo flow throughout the supply chain.
            </h3>
          </div>
        </Reveal>
      </div>
    </div>
  </section>
);

/* ---------- CTA band ---------- */
const CTA = () => (
  <section className="cta-band-wrap" id="contact">
    <Reveal className="cta-band">
      <div className="cta-band-media" aria-hidden="true">
        <AutoVideo
          className="cta-band-video"
          src="assets/media/videos/contact/flow-contact-section.mp4"
          preload="metadata"
        />
      </div>
      <div className="cta-band-overlay" aria-hidden="true"></div>
      <div className="text">
        <h2>End-to-end shipping.<br/><em>One conversation away.</em></h2>
        <p className="sub">Tell us where your cargo needs to go and our team will come back with routing options, capacity and a tailored quote.</p>
      </div>
      <div className="row">
        <div className="cta-actions">
          <a href="mailto:hello@oceanis.example" className="btn-primary">
            Get in touch
            <span className="arrow"><Icon name="arrow" size={12}/></span>
          </a>
          <a href={homeUrl("#services")} className="btn-ghost">
            Explore services
          </a>
        </div>
      </div>
    </Reveal>
  </section>
);

/* ---------- Footer ---------- */
const Footer = () => (
  <footer className="footer">
    <div className="container">
      <div className="footer-grid">
        <div className="footer-brand">
          <LazyImage src="assets/images/logos/logo-main.png" alt="Oceanis" />
          <p>An integrated shipping and logistics company, headquartered in the UAE. Built for the trade corridors of the Indian Ocean.</p>
        </div>
        <div className="footer-col">
          <h4>Services</h4>
          <a href={homeUrl("#services")}>Sea cargo</a>
          <a href={homeUrl("#services")}>Logistics &amp; transport</a>
          <a href={homeUrl("#services")}>Ship chartering</a>
        </div>
        <div className="footer-col">
          <h4>Network</h4>
          <a href={homeUrl("#network")}>East Africa</a>
          <a href={homeUrl("#network")}>Middle East</a>
          <a href={homeUrl("#network")}>South Asia</a>
          <a href={homeUrl("#network")}>SE Asia &amp; China</a>
        </div>
        <div className="footer-col">
          <h4>Company</h4>
          <a href={homeUrl("#approach")}>About</a>
          <a href={homeUrl("#approach")}>Vision &amp; mission</a>
        </div>
        <div className="footer-col">
          <h4>Contact</h4>
          <a href="mailto:hello@oceanis.example">hello@oceanis.example</a>
        </div>
      </div>
      <div className="footer-bar" style={{marginTop: "40px"}}></div>
      <div className="footer-bottom">
        <span>© 2026 Oceanis Shipping &amp; Logistics. All rights reserved.</span>
        <a href={privacyUrl()}>Privacy</a>
      </div>
    </div>
  </footer>
);

/* ---------- Tweaks Panel ---------- */
const TweaksUI = () => {
  const [t, setT] = useTweaks(DEFAULTS);
  useEffect(() => {
    document.body.classList.toggle("theme-green", t.theme === "green");
    document.body.classList.toggle("theme-navy", t.theme === "navy");
    document.body.classList.toggle("dark", !!t.dark);
  }, [t.theme, t.dark]);

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Brand emphasis">
        <TweakRadio label="Color lead" value={t.theme} onChange={(v) => setT("theme", v)}
          options={[
            { value: "blue",  label: "Blue" },
            { value: "green", label: "Green" },
            { value: "navy",  label: "Navy" },
          ]}/>
        <TweakToggle label="Dark mode" value={t.dark} onChange={(v) => setT("dark", v)}/>
      </TweakSection>
    </TweaksPanel>
  );
};

/* ---------- App ---------- */
const App = () => {
  const [t] = useTweaks(DEFAULTS);
  return (
    <>
      <Nav/>
      <Hero/>
      <Bento/>
      <Services/>
      <Coverage/>
      <Approach/>
      <CTA/>
      <Footer/>
      <TweaksUI/>
    </>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
