// FNN Dev — home page prototype
// Dark, technical developer portfolio. Variations exposed as Tweaks.

const { useState, useEffect, useRef } = React;

/* ----------------------------------------------------------------- */
/* Styles                                                            */
/* ----------------------------------------------------------------- */
const CSS = `
.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 32px; }

/* ---- background layer ---- */
.bg-layer { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
body[data-bg="grid"] .bg-layer {
  background-image:
    linear-gradient(rgba(255,255,255,0.022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.022) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 78%);
          mask-image: radial-gradient(120% 90% at 50% 0%, #000 35%, transparent 78%);
}
body[data-bg="gradient"] .bg-layer {
  background:
    radial-gradient(70% 50% at 50% -8%, var(--accent-soft), transparent 70%),
    radial-gradient(40% 30% at 85% 8%, rgba(120,160,255,0.05), transparent 70%);
}
body[data-bg="grid"] .bg-layer::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(60% 40% at 50% -6%, var(--accent-soft), transparent 72%);
}
.page { position: relative; z-index: 1; }

/* ---- nav ---- */
.nav { position: sticky; top: 0; z-index: 50;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  border-bottom: 1px solid transparent; transition: border-color .3s, background .3s; }
.nav[data-scrolled="true"] { border-bottom-color: var(--border); background: color-mix(in srgb, var(--bg) 88%, transparent); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-link { color: var(--text-dim); font-size: 14px; font-weight: 450; padding: 8px 12px; border-radius: 8px; transition: color .15s, background .15s; }
.nav-link:hover { color: var(--text); background: rgba(255,255,255,0.04); }
.nav-right { display: flex; align-items: center; gap: 14px; }

/* ---- brand ---- */
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex: 0 0 auto;
  background: linear-gradient(160deg, color-mix(in srgb, var(--accent) 92%, #fff 8%), color-mix(in srgb, var(--accent) 70%, #000 30%));
  box-shadow: 0 0 0 1px rgba(255,255,255,0.10) inset, 0 6px 18px -8px var(--accent); }
.brand-name { font-weight: 600; font-size: 15.5px; letter-spacing: -0.01em; }
.brand-name .dim { color: var(--text-faint); font-weight: 500; }

/* ---- buttons ---- */
.btn { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-sans); white-space: nowrap;
  font-size: 14px; font-weight: 500; padding: 10px 16px; border-radius: 9px; cursor: pointer;
  border: 1px solid transparent; transition: transform .12s, background .15s, border-color .15s, box-shadow .15s; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: #061018; font-weight: 600;
  box-shadow: 0 1px 0 rgba(255,255,255,0.25) inset, 0 10px 24px -12px var(--accent); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 88%, #fff 12%); }
.btn-ghost { background: rgba(255,255,255,0.03); border-color: var(--border-strong); color: var(--text); }
.btn-ghost:hover { background: rgba(255,255,255,0.07); border-color: var(--text-faint); }
.btn-sm { padding: 8px 13px; font-size: 13px; }
.btn-link { color: var(--text); padding: 0; background: none; border: none; font-weight: 500; font-size: 14px;
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.btn-link .arrow { transition: transform .18s; color: var(--accent); }
.btn-link:hover .arrow { transform: translateX(3px); }

/* ---- eyebrow / pills ---- */
.eyebrow { font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--accent); }
.pill { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12px; white-space: nowrap;
  letter-spacing: 0.02em; color: var(--text-dim); padding: 6px 12px 6px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: rgba(255,255,255,0.02); }
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.dot.live { background: #34d399; box-shadow: 0 0 0 3px rgba(52,211,153,0.16); animation: pulse 2.4s infinite; }
.dot.dev { background: #f5b455; box-shadow: 0 0 0 3px rgba(245,180,85,0.16); }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.45} }

/* ---- hero ---- */
.hero { padding: clamp(56px, 9vw, 120px) 0 clamp(48px, 7vw, 92px); }
.hero-grid { display: grid; gap: 56px; align-items: center; }
.hero h1 { font-size: clamp(2.5rem, 5.4vw, 4.1rem); line-height: 1.03; letter-spacing: -0.035em;
  font-weight: 600; margin: 22px 0 0; text-wrap: balance; }
.hero h1 .soft { color: var(--text-dim); }
.hero .lede { font-size: clamp(1rem, 1.5vw, 1.22rem); line-height: 1.6; color: var(--text-dim);
  margin: 22px 0 0; max-width: 46ch; text-wrap: pretty; }
.hero-cta { display: flex; gap: 12px; margin-top: 34px; flex-wrap: wrap; }
.hero-meta { display: flex; gap: 28px; margin-top: 40px; flex-wrap: wrap; }
.hero-meta .stat .k { font-family: var(--font-mono); font-size: 13px; color: var(--text); font-weight: 500; }
.hero-meta .stat .l { font-size: 12.5px; color: var(--text-faint); margin-top: 3px; }

/* layout: centered */
body[data-hero="centered"] .hero-grid { grid-template-columns: 1fr; justify-items: center; text-align: center; }
body[data-hero="centered"] .hero-copy { max-width: 720px; }
body[data-hero="centered"] .hero .lede { margin-left: auto; margin-right: auto; }
body[data-hero="centered"] .hero-cta, body[data-hero="centered"] .hero-meta { justify-content: center; }
body[data-hero="centered"] .hero-visual { display: none; }
/* layout: split */
body[data-hero="split"] .hero-grid { grid-template-columns: 1.05fr 0.95fr; }
/* layout: left */
body[data-hero="left"] .hero-grid { grid-template-columns: 1fr; }
body[data-hero="left"] .hero-copy { max-width: 760px; }
body[data-hero="left"] .hero-visual { display: none; }

/* ---- timeconv mock (faithful to the real app) ---- */
.tc { --tc-bg:#0a0a0b; --tc-text:#f4f2ec; --tc-dim:#7e7e79; --tc-faint:#56564f; --tc-amber:#e8b24c;
  --tc-line: rgba(255,255,255,0.07);
  position: relative; width: min(380px, 100%); margin: 0 auto;
  background: var(--tc-bg); color: var(--tc-text); border-radius: 30px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.10);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', sans-serif;
  box-shadow: 0 0 0 9px #15151a, 0 0 0 10px rgba(255,255,255,0.06), 0 60px 90px -50px rgba(0,0,0,0.95); }
.tc-top { display:flex; align-items:center; justify-content:space-between; padding: 22px 22px 0; }
.tc-burger { display:flex; flex-direction:column; gap:4px; }
.tc-burger span { width:22px; height:1.5px; background: var(--tc-text); border-radius:2px; opacity:.92; }
.tc-now { display:flex; align-items:center; gap:9px; font-size:12.5px; letter-spacing:0.02em; color: var(--tc-dim);
  font-variant-numeric: tabular-nums; }
.tc-now .rdot { width:6px; height:6px; border-radius:50%; background:#e5484d; }
.tc-now .z { color: var(--tc-text); }
.tc-rule { height:1px; background: var(--tc-line); margin: 16px 0 0; }
.tc-body { padding: 26px 24px 0; }
.tc-label { font-size:12px; letter-spacing:0.26em; text-transform:uppercase; color: var(--tc-dim); font-weight:500; }
.tc-time { font-size: 76px; line-height:0.92; font-weight:300; letter-spacing:-0.03em; margin-top:6px;
  font-variant-numeric: tabular-nums; }
.tc-time .colon { margin: 0 0.01em; }
.tc-date { font-size:15px; color: var(--tc-dim); margin-top:14px; letter-spacing:0.01em; }
.tc-date .cal { opacity:.7; margin-left:6px; }
.tc-port { display:flex; align-items:baseline; gap:11px; margin-top:14px; }
.tc-port .code { font-size:26px; font-weight:400; letter-spacing:-0.01em; }
.tc-port .city { font-size:17px; color: var(--tc-text); }
.tc-port .chev { color: var(--tc-dim); font-size:13px; transform: translateY(-1px); }
.tc-zone { font-size:13.5px; color: var(--tc-faint); margin-top:7px; }
.tc-diff { text-align:center; padding: 30px 0 28px; }
.tc-diff .l { font-size:11.5px; letter-spacing:0.24em; text-transform:uppercase; color: var(--tc-faint); }
.tc-diff .v { font-size:40px; font-weight:300; color: var(--tc-amber); letter-spacing:-0.02em; margin-top:8px; }
.tc-actions { display:grid; grid-template-columns: repeat(3,1fr); border-top:1px solid var(--tc-line); margin-top:20px; }
.tc-actions button { background:none; border:none; color: var(--tc-text); font-family:inherit;
  font-size:11px; letter-spacing:0.13em; text-transform:uppercase; padding:20px 6px; cursor:pointer; }
.tc-actions button + button { border-left:1px solid var(--tc-line); }

/* ---- converter: light theme ---- */
.tc.light { --tc-bg:#f3f0e8; --tc-text:#1b1b19; --tc-dim:#83817a; --tc-faint:#aaa79d; --tc-amber:#a8631d; --tc-line: rgba(0,0,0,0.09);
  border-color: rgba(0,0,0,0.08);
  box-shadow: 0 0 0 9px #e8e4d9, 0 0 0 10px rgba(0,0,0,0.05), 0 60px 90px -50px rgba(0,0,0,0.45); }

/* ---- airport search screen ---- */
.tcs { position:relative; width:min(380px,100%); margin:0 auto; border-radius:30px; overflow:hidden;
  background:#f3f0e8; color:#1b1b19; border:1px solid rgba(0,0,0,0.08);
  font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sans-serif;
  box-shadow: 0 0 0 9px #e8e4d9, 0 0 0 10px rgba(0,0,0,0.05), 0 60px 90px -50px rgba(0,0,0,0.45);
  --s-dim:#83817a; --s-faint:#aaa79d; --s-amber:#a8631d; --s-line:rgba(0,0,0,0.08); }
.tcs::after { content:""; position:absolute; left:0; right:0; bottom:0; height:90px; pointer-events:none;
  background:linear-gradient(transparent, #f3f0e8); }
.tcs-top { display:flex; align-items:center; justify-content:space-between; padding:22px 22px 18px; border-bottom:1px solid var(--s-line); }
.tcs-menu { font-size:12px; letter-spacing:0.24em; color:var(--s-dim); }
.tcs-x { color:#1b1b19; font-size:17px; line-height:1; }
.tcs-body { padding:18px 22px 0; }
.tcs-back { display:flex; align-items:center; gap:6px; font-size:14px; color:#1b1b19; }
.tcs-h { font-size:12px; letter-spacing:0.24em; color:var(--s-dim); margin:16px 0 14px; }
.tcs-search { border:1px solid rgba(0,0,0,0.16); border-radius:11px; padding:13px 15px; color:var(--s-faint); font-size:14px; }
.tcs-list { margin-top:6px; }
.tcs-row { display:flex; align-items:center; gap:14px; padding:14px 0; border-bottom:1px solid var(--s-line); }
.tcs-row .code { font-size:23px; font-weight:400; min-width:52px; letter-spacing:-0.01em; }
.tcs-row .meta { flex:1; min-width:0; }
.tcs-row .meta .city { font-size:16px; }
.tcs-row .meta .full { font-size:12px; color:var(--s-dim); margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tcs-row .act { color:var(--s-amber); font-size:17px; flex:0 0 auto; width:20px; text-align:center; }
.tcs-row .act.rm { color:#9c9a90; }
.tcs-sec { font-size:12px; letter-spacing:0.24em; color:var(--s-dim); margin:22px 0 2px; }

/* ---- TimeConv showcase trio ---- */
.showcase { margin-top: 4px; }
.trio { display:flex; justify-content:center; align-items:flex-start; gap: clamp(14px,2.2vw,30px); padding: 44px 0 8px; }
.device { flex:0 0 auto; width: 290px; display:flex; flex-direction:column; align-items:center; gap:20px; }
.device .tc, .device .tcs { width: 290px; }
.device.raise { transform: translateY(-32px); z-index:2; }
.device.dip { transform: translateY(16px); }
.device .cap { font-family:var(--font-mono); font-size:12px; letter-spacing:0.04em; color:var(--text-faint); text-align:center; }
.device .cap b { color: var(--text-dim); font-weight:500; }
.trio .tc-time { font-size: 58px; }
.trio .tc-body { padding: 22px 20px 0; }
.trio .tc-diff { padding: 22px 0 22px; }
.trio .tc-diff .v { font-size: 33px; }
.trio .tc-actions button { padding:17px 4px; font-size:10px; letter-spacing:0.1em; }
.trio .tcs-body { padding: 16px 20px 0; }
.trio .tcs::after { height:70px; }

.tc-info { display:flex; flex-direction:column; align-items:center; text-align:center; gap:18px; margin-top: clamp(40px,6vw,68px); }
.tc-info-head { display:flex; align-items:center; gap:13px; text-align:left; }
.tc-info-head .nm { font-size:18px; font-weight:600; letter-spacing:-0.015em; }
.tc-info-head .sub { font-family:var(--font-mono); font-size:12px; color:var(--text-faint); margin-top:3px; }
.tc-info .chips { justify-content:center; max-width:580px; }

@media (max-width: 1000px) {
  .trio { overflow-x:auto; justify-content:flex-start; gap:20px; padding: 34px 4px 16px;
    scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
  .trio::-webkit-scrollbar { display:none; }
  .device { scroll-snap-align:center; }
  .device.raise, .device.dip { transform:none; }
}

/* ---- sections ---- */
.section { padding: clamp(48px, 7vw, 90px) 0; position: relative; }
.section-head { display:flex; align-items:flex-end; justify-content:space-between; gap:24px; margin-bottom: 36px; }
.section-head h2 { font-size: clamp(1.7rem, 3vw, 2.1rem); letter-spacing:-0.025em; font-weight:600; margin: 12px 0 0; }
.section-head p { color: var(--text-dim); margin: 10px 0 0; font-size: 15px; max-width: 52ch; }
.section-divider { height:1px; background: linear-gradient(90deg, transparent, var(--border), transparent); }

/* ---- app cards ---- */
.app-grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(340px,1fr)); gap: 18px; }
.app-card { position: relative; border-radius: var(--radius); padding: 24px; transition: transform .18s, border-color .18s, background .18s, box-shadow .18s; }
.app-card:hover { transform: translateY(-3px); }
/* card style: minimal */
body[data-card="minimal"] .app-card { background: transparent; border:1px solid transparent; }
body[data-card="minimal"] .app-card:hover { background: rgba(255,255,255,0.025); }
body[data-card="minimal"] .app-grid { gap: 6px; }
body[data-card="minimal"] .app-card { border-radius: 12px; }
/* card style: bordered */
body[data-card="bordered"] .app-card { background: rgba(255,255,255,0.012); border:1px solid var(--border); }
body[data-card="bordered"] .app-card:hover { border-color: var(--border-strong); background: rgba(255,255,255,0.03); }
/* card style: elevated */
body[data-card="elevated"] .app-card { background: linear-gradient(180deg, var(--surface), var(--bg-2)); border:1px solid var(--border); box-shadow: var(--shadow-card); }
body[data-card="elevated"] .app-card:hover { border-color: var(--accent-line); box-shadow: 0 1px 0 rgba(255,255,255,0.05) inset, 0 30px 60px -34px rgba(0,0,0,0.9), 0 0 0 1px var(--accent-line); }

.app-head { display:flex; align-items:flex-start; gap:16px; }
.app-ico { width:54px; height:54px; border-radius:13px; flex:0 0 auto; box-shadow: 0 0 0 1px rgba(255,255,255,0.08) inset, 0 8px 22px -10px rgba(0,0,0,0.7); }
.app-title { display:flex; flex-direction:column; gap:6px; min-width:0; }
.app-title .nm { font-size:18px; font-weight:600; letter-spacing:-0.015em; }
.app-title .tg { font-size:13.5px; color: var(--text-dim); line-height:1.45; }
.app-status { display:inline-flex; align-items:center; gap:7px; font-family:var(--font-mono); font-size:11px; letter-spacing:0.04em; color: var(--text-dim); }
.app-status.dev { color: #e6b36a; }
.app-status.live { color: #5fd6a4; }
.chips { display:flex; flex-wrap:wrap; gap:7px; margin-top:18px; }
.chip { font-family: var(--font-mono); font-size:11.5px; color: var(--text-dim); padding:5px 9px; border-radius:7px;
  border:1px solid var(--border); background: rgba(255,255,255,0.02); }
.app-foot { display:flex; align-items:center; justify-content:space-between; margin-top:22px; }
.appstore { display:inline-flex; align-items:center; gap:9px; padding:8px 13px; border-radius:9px;
  border:1px solid var(--border-strong); background: rgba(255,255,255,0.03); transition: background .15s, border-color .15s; }
.appstore:hover { background: rgba(255,255,255,0.07); border-color: var(--text-faint); }
.appstore .sub { font-size:9px; color: var(--text-faint); line-height:1; text-transform:uppercase; letter-spacing:0.1em; }
.appstore .main { font-size:13px; font-weight:600; line-height:1.2; margin-top:2px; }

.card-soon { opacity: 0.96; }
.card-soon .app-ico { filter: saturate(0.5) brightness(0.92); }

/* ---- footer ---- */
.footer { border-top:1px solid var(--border); padding: 48px 0 56px; margin-top: 40px; }
.footer-inner { display:flex; justify-content:space-between; gap:32px; flex-wrap:wrap; }
.footer-col h4 { font-family:var(--font-mono); font-size:11px; letter-spacing:0.16em; text-transform:uppercase; color: var(--text-faint); margin:0 0 14px; font-weight:500; }
.footer-col a { display:block; color: var(--text-dim); font-size:14px; padding:5px 0; transition:color .15s; }
.footer-col a:hover { color: var(--text); }
.footer-cols { display:flex; gap:72px; flex-wrap:wrap; }
.footer-bottom { display:flex; justify-content:space-between; align-items:center; gap:16px; margin-top:44px; padding-top:24px; border-top:1px solid var(--border); flex-wrap:wrap; }
.footer-bottom .copy { font-size:13px; color: var(--text-faint); }
.footer-brand-note { font-size:13px; color: var(--text-dim); max-width: 30ch; line-height:1.55; margin-top:14px; }

@media (max-width: 880px) {
  body[data-hero="split"] .hero-grid { grid-template-columns: 1fr; }
  body[data-hero="split"] .hero-visual { display:block; }
  .nav-links { display:none; }
  .section-head { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 560px) {
  .container { padding: 0 20px; }
  .app-grid { grid-template-columns: 1fr; }
}
`;

/* ----------------------------------------------------------------- */
/* Helpers + icons                                                   */
/* ----------------------------------------------------------------- */
function hexToRgba(hex, a) {
  const h = hex.replace('#',''); const n = parseInt(h.length===3 ? h.split('').map(c=>c+c).join('') : h, 16);
  return `rgba(${(n>>16)&255},${(n>>8)&255},${n&255},${a})`;
}

function BrandMark({ size = 30 }) {
  return (
    <div className="brand-mark" style={{ width:size, height:size }}>
      <svg width={size*0.56} height={size*0.56} viewBox="0 0 24 24" fill="none">
        <path d="M5 19V5h13" stroke="#061018" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/>
        <path d="M5 12h9" stroke="#061018" strokeWidth="2.6" strokeLinecap="round"/>
      </svg>
    </div>
  );
}

function TimeConvIcon({ size = 54, radius = 13 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 54 54" style={{ borderRadius: radius }}>
      <rect width="54" height="54" rx={radius} fill="#0a0a0b"/>
      <rect x="0.5" y="0.5" width="53" height="53" rx={radius-0.5} fill="none" stroke="rgba(255,255,255,0.08)"/>
      <circle cx="27" cy="26" r="15" fill="none" stroke="#f4f2ec" strokeWidth="1.6"/>
      <path d="M27 17.5V26l6 3.4" stroke="#e8b24c" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
    </svg>
  );
}

const Arrow = () => (<svg className="arrow" width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M3 8h9M8.5 4l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>);
const AppleGlyph = () => (<svg width="17" height="17" viewBox="0 0 24 24" fill="var(--text)"><path d="M16.4 12.7c0-2.3 1.9-3.4 2-3.5-1.1-1.6-2.8-1.8-3.4-1.8-1.4-.1-2.8.9-3.5.9-.7 0-1.8-.8-3-.8-1.5 0-2.9.9-3.7 2.3-1.6 2.7-.4 6.7 1.1 8.9.7 1.1 1.6 2.3 2.7 2.2 1.1 0 1.5-.7 2.8-.7s1.6.7 2.8.7c1.1 0 1.9-1.1 2.6-2.1.8-1.2 1.2-2.3 1.2-2.4-.1 0-2.2-.9-2.3-3.4zM14.1 5.5c.6-.7 1-1.7.9-2.7-.9 0-1.9.6-2.5 1.3-.5.6-1 1.6-.9 2.6 1 .1 2-.5 2.5-1.2z"/></svg>);

/* ----------------------------------------------------------------- */
/* TimeConv screens — faithful recreations of the real app           */
/* ----------------------------------------------------------------- */
function pad(n){ return String(n).padStart(2,'0'); }
const MONTHS = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'];
function zuluStr(d){ return `${pad(d.getUTCDate())} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}  ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}Z`; }

function ConverterScreen({ theme = 'dark', live = false, dep, arr, diff }) {
  const [now, setNow] = useState(new Date());
  useEffect(() => { if (!live) return; const id = setInterval(()=>setNow(new Date()), 1000); return ()=>clearInterval(id); }, [live]);
  const Time = ({ v }) => { const [h,m] = v.split(':'); return (<div className="tc-time">{h}<span className="colon">:</span>{m}</div>); };
  return (
    <div className={"tc" + (theme === 'light' ? ' light' : '')}>
      <div className="tc-top">
        <div className="tc-burger"><span></span><span></span><span></span></div>
        <div className="tc-now"><span className="rdot"></span><span>NOW</span><span className="z">{zuluStr(now)}</span></div>
      </div>
      <div className="tc-rule"></div>
      <div className="tc-body">
        <div className="tc-label">Departure</div>
        <Time v={dep.time} />
        <div className="tc-date">{dep.date}<span className="cal">▢</span></div>
        <div className="tc-port"><span className="code">{dep.code}</span><span className="city">{dep.city}</span><span className="chev">⌄</span></div>
        <div className="tc-zone">{dep.zone}</div>
        <div className="tc-diff"><div className="l">Time Difference</div><div className="v">{diff}</div></div>
        <div className="tc-label">Arrival</div>
        <Time v={arr.time} />
        <div className="tc-date">{arr.date}<span className="cal">▢</span></div>
        <div className="tc-port"><span className="code">{arr.code}</span><span className="city">{arr.city}</span><span className="chev">⌄</span></div>
        <div className="tc-zone">{arr.zone}</div>
      </div>
      <div className="tc-actions">
        <button>Set Alarm</button><button>Swap</button><button>Count Down</button>
      </div>
    </div>
  );
}

const HKG = { time:'04:00', date:'Sat · 06 JUN 2026', code:'HKG', city:'Hong Kong', zone:'Hong Kong Standard Time · UTC+8' };
const UTC = { time:'20:00', date:'Fri · 05 JUN 2026', code:'UTC', city:'UTC', zone:'Greenwich Mean Time · UTC' };
const HNL = { time:'10:00', date:'Fri · 05 JUN 2026', code:'HNL', city:'Honolulu', zone:'Hawaii–Aleutian Standard Time · UTC-10' };

function TimeConvMock() {
  return (
    <div className="hero-visual">
      <ConverterScreen theme="dark" live={true} dep={HKG} arr={UTC} diff="−8h" />
    </div>
  );
}

function AirportSearchScreen() {
  const selected = [
    ['SZX','Shenzhen',"Shenzhen Bao'an International · ZGSZ · China"],
    ['TPE','Taipei','Taoyuan International · RCTP · Taiwan'],
    ['ICN','Seoul','Incheon International · RKSI · South Korea'],
    ['NRT','Tokyo','Narita International · RJAA · Japan'],
  ];
  const airports = [
    ['UTC','UTC','Coordinated Universal Time · UTC · Universal','check'],
    ['ANC','Anchorage','Ted Stevens Anchorage Int’l · PANC · United States','check'],
    ['HNL','Honolulu','Daniel K. Inouye Int’l · PHNL · United States','check'],
    ['YVR','Vancouver','Vancouver International · CYVR · Canada','add'],
    ['SEA','Seattle','Seattle–Tacoma Int’l · KSEA · United States','check'],
  ];
  return (
    <div className="tcs">
      <div className="tcs-top"><span className="tcs-menu">MENU</span><span className="tcs-x">✕</span></div>
      <div className="tcs-body">
        <div className="tcs-back"><span style={{fontSize:'16px'}}>‹</span> Back</div>
        <div className="tcs-h">AIRPORT SEARCH</div>
        <div className="tcs-search">IATA, ICAO, city, airport</div>
        <div className="tcs-list">
          {selected.map(([code,city,full]) => (
            <div className="tcs-row" key={code}>
              <span className="code">{code}</span>
              <span className="meta"><div className="city">{city}</div><div className="full">{full}</div></span>
              <span className="act rm">✕</span>
            </div>
          ))}
          <div className="tcs-sec">AIRPORTS</div>
          {airports.map(([code,city,full,act]) => (
            <div className="tcs-row" key={code}>
              <span className="code">{code}</span>
              <span className="meta"><div className="city">{city}</div><div className="full">{full}</div></span>
              <span className="act">{act === 'check' ? '✓' : '+'}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function Showcase() {
  return (
    <div className="showcase">
      <div className="trio">
        <div className="device dip">
          <AirportSearchScreen />
          <div className="cap"><b>Airport search</b> · IATA / ICAO</div>
        </div>
        <div className="device raise">
          <ConverterScreen theme="light" dep={HKG} arr={HNL} diff="−18h" />
          <div className="cap"><b>Light mode</b> · UTC ⇄ local</div>
        </div>
        <div className="device dip">
          <ConverterScreen theme="dark" dep={HKG} arr={UTC} diff="−8h" />
          <div className="cap"><b>Dark mode</b> · Zulu time</div>
        </div>
      </div>
    </div>
  );
}

/* ----------------------------------------------------------------- */
/* Sections                                                          */
/* ----------------------------------------------------------------- */
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', on); on();
    return () => window.removeEventListener('scroll', on);
  }, []);
  return (
    <nav className="nav" data-scrolled={scrolled}>
      <div className="container nav-inner">
        <a className="brand" href="/">
          <BrandMark />
          <span className="brand-name">FNN&nbsp;Dev</span>
        </a>
        <div className="nav-links">
          <a className="nav-link" href="/#apps">Apps</a>
          <a className="nav-link" href="/about/">About</a>
          <a className="nav-link" href="/privacy/">Privacy</a>
          <a className="nav-link" href="/support/">Support</a>
        </div>
        <div className="nav-right">
          <a className="btn btn-ghost btn-sm" href="/support/">Contact</a>
        </div>
      </div>
    </nav>
  );
}

function Hero() {
  return (
    <header className="hero" id="top">
      <div className="container">
        <div className="hero-grid">
          <div className="hero-copy">
            <span className="pill"><span className="dot"></span>Independent apps · built to airline standards</span>
            <h1>Built to airline<br/><span className="soft">standards.</span></h1>
            <p className="lede">FNN Dev brings the precision, reliability, and restraint the flight deck demands to focused apps for professionals and everyday users. No accounts, no subscriptions, no noise.</p>
            <div className="hero-cta">
              <a className="btn btn-primary" href="/#apps">View Apps <Arrow/></a>
              <a className="btn btn-ghost" href="/support/">Contact</a>
            </div>
            <div className="hero-meta">
              <div className="stat"><div className="k">1 live</div><div className="l">on the App Store</div></div>
              <div className="stat"><div className="k">100% offline</div><div className="l">no data collection</div></div>
              <div className="stat"><div className="k">Long-term</div><div className="l">actively maintained</div></div>
            </div>
          </div>
          <TimeConvMock />
        </div>
      </div>
    </header>
  );
}

function Apps() {
  const features = ['UTC ⇄ Local','Zulu clock','Compare airports','Countdown timers','Auto DST','Widgets','Works offline','No accounts'];
  return (
    <main>
      <section className="section" id="apps">
        <div className="container">
          <div className="section-head">
            <div>
              <span className="eyebrow">Released · On the App Store</span>
              <h2>Meet TimeConv</h2>
              <p>Convert UTC (Zulu) and local time in a tap, compare any two airports, and track flight countdowns — fully offline, no account.</p>
            </div>
            <span className="pill"><span className="dot live"></span>Available now</span>
          </div>

          <Showcase />

          <div className="tc-info">
            <div className="tc-info-head">
              <TimeConvIcon size={48} radius={12} />
              <div>
                <div className="nm">TimeConv</div>
                <div className="sub">Free · Offline · No account</div>
              </div>
            </div>
            <div className="chips">{features.map(f => <span className="chip" key={f}>{f}</span>)}</div>
            <a className="appstore" href="#"><AppleGlyph/><span><span className="sub">Download on the</span><span className="main">App Store</span></span></a>
          </div>
        </div>
      </section>
    </main>
  );
}

function Footer() {
  return (
    <footer className="footer" id="footer">
      <div className="container">
        <div className="footer-inner">
          <div>
            <a className="brand" href="/"><BrandMark/><span className="brand-name">FNN&nbsp;Dev</span></a>
            <p className="footer-brand-note">Independent apps by Satoshi Funeno. Built for reliability and the long run.</p>
          </div>
          <div className="footer-cols">
            <div className="footer-col"><h4>Apps</h4><a href="/#apps">TimeConv</a></div>
            <div className="footer-col"><h4>Company</h4><a href="/about/">About</a><a href="/support/">Support</a></div>
            <div className="footer-col"><h4>Legal</h4><a href="/privacy/">Privacy</a><a href="/privacy/#timeconv">App privacy</a></div>
          </div>
        </div>
        <div className="footer-bottom">
          <span className="copy">© 2026 FNN Dev · Satoshi Funeno</span>
          <span className="copy" style={{ fontFamily:'var(--font-mono)', fontSize:12 }}>fnndev.us</span>
        </div>
      </div>
    </footer>
  );
}

/* ----------------------------------------------------------------- */
/* App + Tweaks                                                       */
/* ----------------------------------------------------------------- */
const ACCENTS = ['#4d9bff','#e8b24c','#38bdf8','#7da2c4'];
const ACCENT_LABELS = { '#4d9bff':'Aviation', '#e8b24c':'TimeConv amber', '#38bdf8':'Sky', '#7da2c4':'Muted' };

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "heroLayout": "split",
  "background": "grid",
  "accent": "#4d9bff"
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--accent', t.accent);
    r.style.setProperty('--accent-soft', hexToRgba(t.accent, 0.12));
    r.style.setProperty('--accent-line', hexToRgba(t.accent, 0.30));
  }, [t.accent]);

  useEffect(() => {
    document.body.dataset.hero = t.heroLayout;
    document.body.dataset.bg = t.background;
  }, [t.heroLayout, t.background]);

  return (
    <React.Fragment>
      <style>{CSS}</style>
      <div className="bg-layer"></div>
      <div className="page">
        <Nav/>
        <Hero/>
        <Apps/>
        <Footer/>
      </div>

      <TweaksPanel>
        <TweakSection label="Layout" />
        <TweakRadio label="Hero" value={t.heroLayout} options={['split','centered','left']} onChange={v=>setTweak('heroLayout', v)} />
        <TweakSection label="Style" />
        <TweakRadio label="Background" value={t.background} options={['plain','grid','gradient']} onChange={v=>setTweak('background', v)} />
        <TweakColor label="Accent" value={t.accent} options={ACCENTS} onChange={v=>setTweak('accent', v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

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