// Shared articles + abstract CSS scenery components.

const ARTICLES = [
  {
    id: 'hiyoshi',
    title: '日吉ダム、灰色の水面',
    titleEn: 'Hiyoshi Dam · A Grey Lake',
    excerpt: 'どんよりとした空の下、新緑の山に抱かれた人造湖。風はなく、水面はただ静かに鈍く光っている。',
    body: [
      '京都市内を北西に抜け、亀岡から園部、そして日吉へ。連休も終わりに近づいた水曜日、朝から空はどんよりと低い。降りそうで降らない、ライダーにとっては一番判断に迷う天気だ。レインウェアはタンクバッグに突っ込んだまま、ひとまず走り出した。',
      '国道四七七号から枝道に入ると、いきなり日吉ダムの堤体が現れる。橋の上から見下ろした湖面は、空をそのまま映して灰色に沈んでいた。両岸の新緑だけが、曇天の下でかえって濃く、青っぽく光っている。',
      'バイクを止めて、欄干に寄りかかる。送電鉄塔が稜線の上を縫って向こうへ続いていて、その下の山々が遠近を畳むように重なる。湖を横切る赤いオイルフェンスだけが、この風景でただ一つの彩度の高い線だった。',
      '釣り船もボートも出ていない。風がないせいで、水音さえほとんどしない。ヘルメットを置いて深く息を吸うと、湿った緑と、わずかに金属の匂い。雨は、もう少し先まで降らないでいてくれるらしい。',
    ],
    scene: 'rain',
    image: 'images/hiyoshi.jpg',
    region: '京都 · 南丹',
    distance: '58 km',
    elevation: '+260 m',
    duration: '2h 50m',
    season: '新緑',
    date: '2026 . 05 . 06',
    issue: 'No. 059',
  },
  {
    id: 'kameoka',
    title: '亀岡、土の匂いの五月',
    titleEn: 'Kameoka in May · Scent of Soil',
    excerpt: '田植え前のひと呼吸。耕されたばかりの土に、新緑の風が抜けていく。',
    body: [
      '京都から国道九号を北西へ。老ノ坂のトンネルを抜けると、亀岡盆地が一気にひらける。ゴールデンウィークの中日、空はよく晴れていて、雲はうすく筋を引くだけ。バイクを路肩に止めて、ヘルメットを脱ぐと、まずやってくるのは土の匂いだった。',
      '田はまだ水を張っていない。耕運機で起こされたばかりの黒い土が、整然と縞を作って広がっている。代掻きまでの、いちばん静かな数日。あぜ道の縁だけが、まぶしいほどの新緑で縁取られていた。',
      '遠くに愛宕の山並みが薄く重なっている。送電鉄塔の向こうで、誰かが軽トラックを止めて立ち話をしているのが見えた。風が抜ける。エンジンの余熱が、ゆっくり冷めていく。',
      'もう少しすれば、ここは一面の水面になる。空をそのまま映して、苗が並ぶ。今日はその直前の景色を見にきた、ということにしておく。',
    ],
    scene: 'fields',
    image: 'images/kameoka.jpg',
    region: '京都 · 亀岡',
    distance: '42 km',
    elevation: '+120 m',
    duration: '2h 20m',
    season: '新緑',
    date: '2026 . 05 . 02',
    issue: 'No. 058',
  },
  {
    id: 'nose',
    title: '能勢、曇天の心地よさ',
    titleEn: 'Nose & Kameoka · All Feels Right',
    excerpt: '亀岡から能勢へ。エンジンを切ると、何も聞こえなかった。それがちょうどよかった。',
    body: [
      '四月の中旬、空は白く低い。雨雲というより毛布みたいな雲が全体を包んでいて、気温はちょうどジャケット一枚で足りるくらい。ファミマの駐車場でヘルメットを脱いだとき、「今日は全部ちょうどいいな」とぼんやり思った。',
      '亀岡を抜けて北へ、能勢方面へ向かう。ゴールデンウィーク前の平日、路面は乾いていて、交通量は少ない。新緑がまだ若い緑をしていて、沿道のソメイヨシノはとっくに散り終えていた。',
      'MT-07のエンジン音が山の斜面に少しだけ響いて、すぐ消える。こういう日は飛ばしたい気持ちにならない。ただ前に進んでいれば十分で、目的地というものがほとんど意味を持たない。',
      '帰り道、また亀岡に戻ってきたとき、空は相変わらず曇ったままだった。それでよかった。晴れていたら、たぶんもっと遠くへ行こうとしていた。',
    ],
    scene: 'clouds',
    image: 'images/nose.jpg',
    region: '京都 · 能勢',
    distance: '75 km',
    elevation: '+340 m',
    duration: '3h 10m',
    season: '春',
    date: '2026 . 04 . 18',
    issue: 'No. 057',
  },
];

// ─────────────────────────────────────────────────────────────────────────────
// Abstract CSS scenery. Each preset is a layered set of absolutely-positioned
// gradients — no SVG illustration, just colored bands suggesting sky/horizon
// /foreground. Accepts a `ratio` for letterboxing variations.

function Scene({ preset, style, children, grain = true }) {
  const presets = {
    fog: {
      bg: 'linear-gradient(180deg, #d5d2cb 0%, #c8c5be 38%, #b6b3ac 66%, #a09c95 100%)',
      layers: [
        // distant ridge
        { bg: 'linear-gradient(180deg, transparent 62%, rgba(120,118,112,0.55) 62%, rgba(120,118,112,0.55) 64%, transparent 64%)' },
        { bg: 'linear-gradient(180deg, transparent 70%, rgba(90,88,82,0.45) 70%, rgba(90,88,82,0.45) 73%, transparent 73%)' },
        // ground
        { bg: 'linear-gradient(180deg, transparent 80%, rgba(58,55,50,0.85) 100%)' },
        // soft mist veil
        { bg: 'linear-gradient(180deg, rgba(245,243,238,0.55) 0%, rgba(245,243,238,0) 55%)' },
      ],
    },
    coast: {
      bg: 'linear-gradient(180deg, #cfd8db 0%, #b8c4c9 35%, #94a5ab 56%, #7d9098 56.5%, #5c727a 100%)',
      layers: [
        { bg: 'linear-gradient(180deg, transparent 55%, rgba(40,55,60,0.18) 56.5%, transparent 60%)' },
        // horizon line crisp
        { bg: 'linear-gradient(180deg, transparent 56.2%, rgba(20,30,35,0.5) 56.3%, transparent 56.5%)' },
        // sea highlights
        { bg: 'repeating-linear-gradient(180deg, transparent 0 8px, rgba(255,255,255,0.04) 8px 9px)', top: '56.5%', height: '43.5%' },
      ],
    },
    dawn: {
      bg: 'linear-gradient(180deg, #2b2436 0%, #54394a 28%, #a26350 52%, #d68a5e 64%, #2a2018 80%, #181210 100%)',
      layers: [
        // sun
        { bg: 'radial-gradient(circle at 72% 62%, #f3c089 0%, rgba(243,192,137,0.5) 8%, transparent 18%)' },
        // ridge silhouette
        { bg: 'linear-gradient(180deg, transparent 70%, #1a1410 70%)', clipPath: 'polygon(0 70%, 14% 67%, 25% 72%, 38% 64%, 55% 70%, 68% 66%, 82% 72%, 100% 68%, 100% 100%, 0 100%)' },
      ],
    },
    clouds: {
      bg: 'linear-gradient(180deg, #6c8aa6 0%, #93b0c5 28%, #c8d4dd 50%, #e9ecec 70%, #f3f3f0 100%)',
      layers: [
        // ridges peeking through cloud sea
        { bg: 'linear-gradient(180deg, transparent 48%, rgba(50,60,70,0.6) 48%, rgba(50,60,70,0.6) 51%, transparent 51%)', clipPath: 'polygon(0 0, 22% 0, 28% 100%, 38% 100%, 44% 0, 62% 0, 68% 100%, 78% 100%, 84% 0, 100% 0, 100% 100%, 0 100%)' },
        // cloud sea
        { bg: 'linear-gradient(180deg, transparent 55%, #f3f3f0 55%, #e3e6e7 100%)' },
        { bg: 'repeating-linear-gradient(180deg, transparent 0 14px, rgba(255,255,255,0.4) 14px 18px)', top: '55%', height: '45%' },
      ],
    },
    ridge: {
      bg: 'linear-gradient(180deg, #b6c5cf 0%, #8aa0a8 32%, #6a7e7a 60%, #4d6058 80%, #2f3e36 100%)',
      layers: [
        // layered hills
        { bg: '#5b6c63', clipPath: 'polygon(0 65%, 18% 56%, 32% 62%, 48% 52%, 64% 60%, 78% 54%, 100% 62%, 100% 100%, 0 100%)' },
        { bg: '#3f4e46', clipPath: 'polygon(0 78%, 22% 70%, 40% 76%, 58% 68%, 72% 74%, 100% 70%, 100% 100%, 0 100%)' },
        { bg: '#283431', clipPath: 'polygon(0 88%, 30% 82%, 56% 88%, 82% 84%, 100% 88%, 100% 100%, 0 100%)' },
      ],
    },
    rain: {
      bg: 'linear-gradient(180deg, #4a4e52 0%, #585b5d 30%, #3e3f3f 60%, #2a2826 100%)',
      layers: [
        // cedar trunks
        { bg: 'repeating-linear-gradient(90deg, transparent 0 26px, rgba(20,15,12,0.5) 26px 29px, transparent 29px 60px)', top: '20%', height: '80%' },
        { bg: 'repeating-linear-gradient(90deg, transparent 0 38px, rgba(10,8,6,0.55) 38px 42px, transparent 42px 95px)', top: '35%', height: '65%' },
        // rain streaks
        { bg: 'repeating-linear-gradient(102deg, transparent 0 18px, rgba(220,225,228,0.16) 18px 19px)' },
        // dark ground
        { bg: 'linear-gradient(180deg, transparent 80%, rgba(8,6,4,0.85) 100%)' },
      ],
    },
    fields: {
      bg: 'linear-gradient(180deg, #6ea8d4 0%, #8fbfde 22%, #b4d6e8 42%, #d6e3d4 56%, #6b8a4c 58%, #4f6a36 64%, #6b5640 72%, #5a4632 82%, #3a3633 92%, #2c2a28 100%)',
      layers: [
        { bg: 'repeating-linear-gradient(96deg, transparent 0 60px, rgba(255,255,255,0.18) 60px 64px, transparent 64px 180px)', top: '0%', height: '38%' },
        { bg: '#5b7a55', clipPath: 'polygon(0 56%, 12% 52%, 22% 55%, 34% 50%, 46% 54%, 58% 51%, 70% 53%, 82% 49%, 92% 52%, 100% 50%, 100% 58%, 0 58%)' },
        { bg: 'repeating-linear-gradient(90deg, #6e9243 0 22px, #5a7c36 22px 38px, #7ea34c 38px 58px, #587a35 58px 78px)', top: '57%', height: '4%' },
        { bg: 'repeating-linear-gradient(82deg, transparent 0 14px, rgba(20,12,8,0.18) 14px 16px)', top: '61%', height: '21%' },
        { bg: 'linear-gradient(180deg, transparent 81%, #6b8540 81%, #54702f 83%, transparent 83%)' },
        { bg: 'linear-gradient(180deg, transparent 95%, #efece4 95%, #efece4 95.7%, transparent 95.7%)' },
      ],
    },
  };
  const p = presets[preset] || presets.fog;
  return (
    <div style={{
      position: 'relative', overflow: 'hidden', background: p.bg,
      ...style,
    }}>
      {p.layers.map((layer, i) => (
        <div key={i} style={{
          position: 'absolute', inset: 0,
          background: layer.bg,
          clipPath: layer.clipPath,
          top: layer.top, height: layer.height,
        }} />
      ))}
      {grain && (
        <div style={{
          position: 'absolute', inset: 0, pointerEvents: 'none',
          background: 'radial-gradient(rgba(0,0,0,0.18) 1px, transparent 1px)',
          backgroundSize: '3px 3px', opacity: 0.18, mixBlendMode: 'multiply',
        }} />
      )}
      {children}
    </div>
  );
}

// Decorative route line — a tiny abstract "map" shown alongside metadata.
function RouteLine({ width = 80, height = 24, stroke = 'currentColor', variant = 0 }) {
  const paths = [
    'M2 18 C 14 18, 18 6, 30 6 S 50 20, 62 14 S 76 4, 78 6',
    'M2 14 C 16 4, 26 22, 40 12 S 60 4, 78 18',
    'M2 8 L 18 8 C 26 8, 28 18, 36 18 L 56 18 C 64 18, 66 8, 78 8',
    'M2 20 C 12 12, 20 4, 32 12 S 50 22, 62 12 S 74 6, 78 10',
  ];
  return (
    <svg width={width} height={height} viewBox="0 0 80 24" fill="none" style={{ display: 'block' }}>
      <path d={paths[variant % paths.length]} stroke={stroke} strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round" opacity="0.7" />
      <circle cx="2" cy={variant === 1 ? 14 : variant === 2 ? 8 : variant === 3 ? 20 : 18} r="1.6" fill={stroke} />
      <circle cx="78" cy={variant === 1 ? 18 : variant === 2 ? 8 : variant === 3 ? 10 : 6} r="1.6" fill={stroke} />
    </svg>
  );
}

Object.assign(window, { ARTICLES, Scene, RouteLine });
