// Shared assets and tiny helpers used by all 5 LP variants.
// Keep this lean — each LP supplies its own styling.

// Resolve through window.__resources when running as a standalone bundle,
// otherwise fall back to the on-disk path.
const _R = (typeof window !== 'undefined' && window.__resources) || {};
// SLOT_OVERRIDES is now populated only from the Cloudflare CMS asset map.
const _SLOT = (typeof window !== 'undefined' && window.SLOT_OVERRIDES) || {};
const _A = (id, path) => _SLOT[id] || _R[id] || path;
const { hasText, hasImageRef } = window.SmartlifeEmptyContract;
const COPY = {
  'top.badge': '広島の屋根・外壁・住まいの相談窓口',
  'top.hero.line1': '屋根・外壁・リフォームなど',
  'top.hero.line2a': '建物のご相談は',
  'top.hero.line2b': '株式会社スマートライフに。',
  'top.hero.line2c': '',
  'top.hero.lead1': '住まいの修理は、株式会社スマートライフへ。',
  'top.hero.lead2': '広島での屋根・外壁・住まいのメンテナンスを、ひとつの窓口で承ります。',
  'top.hero.note': '屋根・外壁・雨漏り・内装・水回りまで、住まいの修理を一窓口でご相談いただけます。',
  'top.promise.1.title': '住まいのことを窓口ひとつで',
  'top.promise.1.body': '屋根・外壁・雨漏り・内装・水回りまで、まとめてご相談いただけます。',
  'top.promise.2.title': '広島市・周辺エリア対応',
  'top.promise.2.body': '地域密着で活動しているため、現地確認にも迅速に伺います。',
  'top.promise.3.title': '写真を交えてご説明',
  'top.promise.3.body': '屋根の上など見えにくい場所も、撮影した写真をお見せしながらご説明します。',
  'cta.title': 'お問い合わせ',
  'cta.lead1': '屋根や外壁、住まいのことで気になることはありませんか？',
  'cta.lead2': '小さなことでも、お電話またはメールフォームよりお気軽にご相談ください。',
  'privacy.contact.heading': '個人情報の取り扱いについて',
  'privacy.contact.body': 'いただいたお名前・ご連絡先・ご相談内容は、お問い合わせへのご回答とご相談内容の確認のためにのみ使用します。ご本人の同意なく第三者へ提供することはありません。取り扱いに関するお問い合わせは、お電話（{電話番号}）またはこのフォームよりご連絡ください。',
  'footer.description.1': '広島市・周辺エリアの屋根・外壁・住まいの相談窓口です。',
  'footer.description.2': '気になることがあれば、お電話またはメールでお気軽にお問い合わせください。',
};
const copyText = (id, fallback) => {
  const value = COPY[id];
  return typeof value === 'string' && value.trim() ? value : fallback;
};
// CMSの保存値そのもの（未設定なら undefined、管理者が空にしたなら ''）。
// 「未設定＝既定値を出す／明示的に空＝その要素を隠す」を表示側で区別するために使う。
const rawCopyValue = (id) => {
  const value = COPY[id];
  return typeof value === 'string' ? value : undefined;
};
const slHref = (page) => `index.html?page=${page}`;
const slDetailHref = (page, param, value) => `${slHref(page)}&${param}=${encodeURIComponent(value)}`;
const slServiceHref = (serviceId) => slDetailHref('service-detail', 'service', serviceId);
const slArticleHref = (articleId) => slDetailHref('knowledge-detail', 'article', articleId);
const slCaseHref = (caseId) => slDetailHref('case-detail', 'case', caseId);
const slNavHref = (id) => {
  if (id === 'home') return slHref('top');
  if (id === 'flow') return `${slHref('top')}#flow`;
  return slHref(id);
};
function dialablePhone(value, fallback = '082-299-6008') {
  const normalized = String(value || '')
    .replace(/[０-９]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 0xFEE0))
    .replace(/[－ー―‐‑‒–—]/g, '-')
    .replace(/[＋]/g, '+');
  const match = normalized.match(/(?:\+?81|0)[0-9\s().-]{8,18}/);
  const dial = String(match ? match[0] : normalized).replace(/[^\d+]/g, '');
  return dial || fallback.replace(/[^\d+]/g, '');
}
const ASSETS = {
  logo:       _A('logo',       'assets/logo-smartlife.png'),
  heroLogo:   _A('heroLogo',   'assets/logo-smartlife-deepgreen.png'),
  logoGreen:  _A('logoGreen',  'assets/logo-mark-green-v4.png'),  /* 2026-06-12 image_gen生成のプロ版マーク */
  logoOrange: _A('logoOrange', 'assets/logo-mark-orange-v4.png'),
  logoBlack:  _A('logoBlack',  'assets/smartlife-logo-black.svg'),
  heroMain:   _A('heroMain',   'assets/hero-roof-main-flop-w1200.jpg'), /* slot: HERO-01（既定=反転版。候補: hero-roof-main-w1200 / hero-roof-wide-01-w1400 / hero-roof-wide-02-w1400） */
  heroFlip:   _A('heroFlip',   'assets/hero-roof-main-flop-w1200.jpg'), /* 後方互換（heroMainと同値） */
  heroWide1:  _A('heroWide1',  'assets/hero-roof-wide-01-w1400.jpg'),
  heroWide2:  _A('heroWide2',  'assets/hero-roof-wide-02-w1400.jpg'),
  case1:      _A('case1',      'assets/case-roof-after-01.png'),
  case2:      _A('case2',      'assets/case-roof-after-02.png'),
  case3:      _A('case3',      'assets/case-roof-after-03.png'),
  case4:      _A('case4',      'assets/case-roof-after-04.png'),
  caseYayamaBefore: _A('caseYayamaBefore', 'assets/case-yane-fukikae-before-masaaki-20260526.jpg'),
  caseYayamaAfter:  _A('caseYayamaAfter',  'assets/case-yane-fukikae-after-masaaki-20260526.jpg'),
  caseYayamaFlowCheck: _A('caseYayamaFlowCheck', 'assets/case-yayama-flow-check-sl0589.jpg'),
  caseYayamaFlowWork:  _A('caseYayamaFlowWork',  'assets/case-yayama-flow-work-sl0603.jpg'),
  caseHatashiBefore: _A('caseHatashiBefore', 'assets/case-hatashi-before-sl0581.jpg'),
  caseHatashiAfter:  _A('caseHatashiAfter',  'assets/case-hatashi-after-sl0568.jpg'),
  caseRedBefore:    _A('caseRedBefore',    'assets/case-red-before-sl1081.jpg'),
  caseRedAfter:     _A('caseRedAfter',     'assets/case-red-after-sl1092.jpg'),
  svcLeak:    _A('svcLeak',    'assets/service-leak-w1200.jpg'),
  svcLarge:   _A('svcLarge',   'assets/service-large-w1200.jpg'),
  svcSmall:   _A('svcSmall',   'assets/service-small-w1200.jpg'),
  svcMaint:   _A('svcMaint',   'assets/service-maintenance-real.jpg'),
  svcFull:    _A('svcFull',    'assets/service-full-real.jpg'),
  philosophyPhoto: _A('philosophyPhoto', ''),
  serviceWallReal: _A('serviceWallReal', 'assets/service-wall-real.jpg'),
  serviceGutterReal: _A('serviceGutterReal', 'assets/service-gutter-real.jpg'),
  knowFaq:    _A('knowFaq',    'assets/knowledge-estimate-watercolor.jpg'),
  knowLevel:  _A('knowLevel',  'assets/knowledge-home-repair-watercolor.jpg'),
  knowRoof:   _A('knowRoof',   'assets/knowledge-roof-watercolor.jpg'),
  knowLeakWatercolor: _A('knowLeakWatercolor', 'assets/knowledge-leak-watercolor.jpg'),
  knowRoofWatercolor: _A('knowRoofWatercolor', 'assets/knowledge-roof-watercolor.jpg'),
  knowWallWatercolor: _A('knowWallWatercolor', 'assets/knowledge-wall-watercolor.jpg'),
  knowEstimateWatercolor: _A('knowEstimateWatercolor', 'assets/knowledge-estimate-watercolor.jpg'),
  knowInspectionWatercolor: _A('knowInspectionWatercolor', 'assets/knowledge-inspection-watercolor.jpg'),
  knowHomeRepairWatercolor: _A('knowHomeRepairWatercolor', 'assets/knowledge-home-repair-watercolor.jpg'),
};

// Smartlife real info — never make up numbers
const COMPANY = {
  name: '株式会社スマートライフ',
  area: '広島市周辺',
  phone: '082-299-6008',
  // 受付時間はCMSのcompany.hoursだけから受け取る。repo既定値は持たない。
  hours: '',
  address: '〒733-0035 広島県広島市西区南観音1丁目11-17',
  representative: '角屋 政明',
  established: '2010年5月',
  tagline: '広島の屋根・外壁・住まいの相談を、わかりやすく。',
};

function coverImageAlt(src) {
  const path = String(src || '');
  if (path === ASSETS.heroMain || path === ASSETS.heroFlip) return '青空の下で見える住宅の屋根';
  if (path === ASSETS.heroWide1 || path === ASSETS.heroWide2) return '住宅の屋根と外観';
  if (path === ASSETS.caseYayamaBefore) return '屋根工事の施工前写真';
  if (path === ASSETS.caseYayamaAfter) return '屋根工事の施工後写真';
  if (path === ASSETS.caseYayamaFlowCheck) return '屋根の状態を確認している様子';
  if (path === ASSETS.caseYayamaFlowWork) return '屋根工事の施工中写真';
  if (path === ASSETS.caseHatashiBefore) return '棟板金工事の施工前写真';
  if (path === ASSETS.caseHatashiAfter) return '棟板金工事の施工後写真';
  if (path === ASSETS.caseRedBefore) return '金属屋根の施工前写真';
  if (path === ASSETS.caseRedAfter) return '金属屋根の施工後写真';
  if (path === ASSETS.serviceWallReal) return '外壁工事の参考写真';
  if (path === ASSETS.serviceGutterReal) return '雨樋まわりの参考写真';
  if (path === ASSETS.svcLeak) return '雨漏り修理の参考写真';
  if (path === ASSETS.svcLarge || path === ASSETS.svcSmall || path === ASSETS.svcMaint || path === ASSETS.svcFull) return '住まいの修理の参考写真';
  if (path.indexOf('knowledge-') !== -1) return '住まいのお役立ち情報のイメージ';
  if (path.indexOf('case-') !== -1) return '施工事例の写真';
  if (path.indexOf('service-') !== -1) return 'サービスの参考写真';
  return '';
}

// Service list — 6 categories matching the 01-service-index mock.
// `aliases` keeps legacy service IDs (spot/maint/full/reform) resolvable without touching read-only files.
const SERVICES = [
  {
    id: 'roof',
    aliases: ['full', 'spot'],
    name: '屋根工事' /* slot: TEXT-SERVICE-ROOF-NAME */,
    photo: ASSETS.caseYayamaAfter,
    blurb: _A('svcRoofBlurb', '屋根の葺き替えやカバー工法など、屋根全体を整えます。') /* slot: TEXT-SERVICE-ROOF-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-ROOF-SYMPTOMS */
      { t: '屋根全体の劣化が気になる', d: '部分補修でよいか、全体改修が必要かを現地で確認します。' },
      { t: '葺き替え・カバー工法を検討したい', d: '建物の状態とご希望に合わせて、工法の選択肢を整理します。' },
      { t: '瓦・板金のずれが気になる', d: '台風や強風のあとに見えるずれは、早めに確認しておくと安心です。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-ROOF-DURATIONS */
      { kind: '現地調査', day: '半日程度' },
      { kind: '部分補修', day: '数日〜1週間程度' },
      { kind: '全体改修', day: '1〜2週間程度' },
    ],
  },
  {
    id: 'wall',
    aliases: [],
    name: '外壁工事' /* slot: TEXT-SERVICE-WALL-NAME */,
    photo: ASSETS.serviceWallReal,
    blurb: _A('svcWallBlurb', '外壁の塗装や張り替えで、住まいの印象と耐久性を高めます。') /* slot: TEXT-SERVICE-WALL-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-WALL-SYMPTOMS */
      { t: '外壁のヒビ・剥がれが気になる', d: '塗装だけでよいか、下地やシーリングも含めて確認します。' },
      { t: '外壁の色あせが気になる', d: '塗膜の劣化のサインかどうか、現地で状態を確認します。' },
      { t: '目地のシーリングが傷んできた', d: '目地まわりの状態を見て、補修の必要性を整理します。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-WALL-DURATIONS */
      { kind: '現地確認', day: '半日程度' },
      { kind: '部分補修', day: '数日〜1週間程度' },
      { kind: '全面塗装', day: '1〜2週間程度' },
    ],
  },
  {
    id: 'leak',
    aliases: [],
    name: '雨漏り修理' /* slot: TEXT-SERVICE-LEAK-NAME */,
    photo: ASSETS.svcLeak,
    blurb: _A('svcLeakBlurb', '原因を丁寧に調査し、雨漏りの再発を防ぎます。') /* slot: TEXT-SERVICE-LEAK-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-LEAK-SYMPTOMS */
      { t: '天井・壁にシミが出てきた', d: '雨が降った後だけ広がるなら、雨水の経路がある可能性があります。' },
      { t: '雨の日に音がする', d: '屋根や外壁のどこかから、雨水が入り込んでいる可能性があります。' },
      { t: '台風後に瓦・板金がずれた', d: '見えるずれの他に、隠れたずれがある場合があります。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-LEAK-DURATIONS */
      { kind: '応急処置', day: '半日〜1日程度' },
      { kind: '部分補修', day: '数日〜1週間程度' },
      { kind: '全体改修', day: '1〜2週間程度' },
    ],
  },
  {
    id: 'interior',
    aliases: ['reform'],
    name: '内装・水回り' /* slot: TEXT-SERVICE-INTERIOR-NAME */,
    photo: ASSETS.svcFull,
    blurb: _A('svcInteriorBlurb', 'クロス張り替えや水回りの設備工事まで幅広く対応します。') /* slot: TEXT-SERVICE-INTERIOR-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-INTERIOR-SYMPTOMS */
      { t: 'クロスの汚れ・剥がれが気になる', d: '部屋ごとの張り替えなど、必要な範囲からご相談いただけます。' },
      { t: '水回りの設備が古くなってきた', d: '使い方やご希望に合わせて、設備の入れ替えをご提案します。' },
      { t: '内装や水回りもまとめて相談したい', d: '屋根・外壁以外の住まいの修理も、窓口を分けずにご相談いただけます。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-INTERIOR-DURATIONS */
      { kind: '現地確認', day: '半日程度' },
      { kind: '部分工事', day: '数日〜1週間程度' },
      { kind: '複数箇所', day: '内容により要確認' },
    ],
  },
  {
    id: 'exterior',
    aliases: [],
    name: '玄関・外構' /* slot: TEXT-SERVICE-EXTERIOR-NAME */,
    photo: ASSETS.svcSmall,
    blurb: _A('svcExteriorBlurb', '玄関まわりや外構の工事で、快適な住まいに。') /* slot: TEXT-SERVICE-EXTERIOR-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-EXTERIOR-SYMPTOMS */
      { t: '玄関まわりの傷みが気になる', d: '玄関ドアや土間まわりの状態を見て、必要な工事を整理します。' },
      { t: 'フェンス・塀の傾きや劣化がある', d: '安全面も含めて現地で確認し、補修の方法をご案内します。' },
      { t: '外まわりをまとめて整えたい', d: '気になる箇所を整理し、優先順位をつけてご提案します。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-EXTERIOR-DURATIONS */
      { kind: '現地確認', day: '半日程度' },
      { kind: '部分工事', day: '数日〜1週間程度' },
      { kind: '外構全体', day: '内容により要確認' },
    ],
  },
  {
    id: 'whole',
    aliases: ['maint'],
    name: '住まい全体の相談' /* slot: TEXT-SERVICE-WHOLE-NAME */,
    photo: ASSETS.svcMaint,
    blurb: _A('svcWholeBlurb', 'リフォームや将来の計画まで、住まい全体のご相談を承ります。') /* slot: TEXT-SERVICE-WHOLE-BLURB */,
    symptoms: [
      /* slot: TEXT-SERVICE-WHOLE-SYMPTOMS */
      { t: '築年数が経って状態を確認したい', d: '屋根材や板金まわりの状態を見て、必要な対応を整理します。' },
      { t: '台風・大雨のあとに点検したい', d: '普段見えにくい屋根の上も、写真を交えて確認します。' },
      { t: 'どこから手を付ければよいか相談したい', d: '気になる箇所を整理し、優先順位をつけてご提案します。' },
    ],
    durations: [
      /* slot: TEXT-SERVICE-WHOLE-DURATIONS */
      { kind: '現地確認', day: '半日程度' },
      { kind: '軽微補修', day: '1日〜数日程度' },
      { kind: '定期対応', day: '内容により要確認' },
    ],
  },
];

// Generic placeholder for "photo we don't have yet"
function PhotoPlaceholder({ label, ratio = '16/9', tone = 'warm', radius = 12, style }) {
  const tokens = window.R3_TOK;
  const bgA = tone === 'warm' ? tokens.placeholderWarmA : tokens.placeholderCoolA;
  const bgB = tone === 'warm' ? tokens.placeholderWarmB : tokens.placeholderCoolB;
  return (
    <div
      style={{
        aspectRatio: ratio,
        width: '100%',
        background: `repeating-linear-gradient(135deg, ${bgA} 0 12px, ${bgB} 12px 24px)`,
        borderRadius: radius,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: tokens.placeholderText, fontFamily: 'ui-monospace, "SF Mono", Menlo, monospace',
        fontSize: 12, letterSpacing: 0.5,
        ...style,
      }}
    >
      [ {label} ]
    </div>
  );
}

// Cropping helper: cover-fit image inside a fixed aspect box
function CoverImg({ src, srcSet, sizes, alt, ratio = '16/9', radius = 0, style, loading = 'lazy', decoding = 'async', fetchPriority, priority = false, dataEmptyContract, dataServiceId }) {
  const imageLoading = priority ? 'eager' : loading;
  const imageFetchPriority = priority ? 'high' : fetchPriority;
  const [failed, setFailed] = React.useState(false);
  React.useEffect(() => { setFailed(false); }, [src]);
  const [intrinsicWidth, intrinsicHeight] = ratio.split('/').map((value) => Number(value));
  const imageAlt = alt == null ? coverImageAlt(src) : alt;
  const tokens = window.R3_TOK;
  if (!src || failed) {
    return (
      <div
        aria-hidden="true"
        {...(dataEmptyContract ? { 'data-empty-contract': dataEmptyContract } : {})}
        {...(dataServiceId ? { 'data-service-id': dataServiceId } : {})}
        style={{
          aspectRatio: ratio,
          width: '100%',
          borderRadius: radius,
          background: `linear-gradient(135deg, ${tokens.imageFallbackA}, ${tokens.imageFallbackWarmB})`,
          ...style,
        }}
      />
    );
  }
  return (
    <div
      {...(dataEmptyContract ? { 'data-empty-contract': dataEmptyContract } : {})}
      {...(dataServiceId ? { 'data-service-id': dataServiceId } : {})}
      style={{ aspectRatio: ratio, width: '100%', overflow: 'hidden', borderRadius: radius, ...style }}
    >
      <img
        src={src}
        {...(srcSet ? { srcSet } : {})}
        {...(sizes ? { sizes } : {})}
        alt={imageAlt}
        loading={imageLoading}
        decoding={decoding}
        {...(intrinsicWidth && intrinsicHeight ? { width: intrinsicWidth, height: intrinsicHeight } : {})}
        {...(imageFetchPriority ? { fetchpriority: imageFetchPriority } : {})}
        onError={() => setFailed(true)}
        style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
      />
    </div>
  );
}

// Stroke-only inline icons — Lucide (https://lucide.dev) path data, standard
// attrs (viewBox 0 0 24 24 / stroke currentColor / strokeWidth 2 / round caps & joins).
// Key names are stable API — only the path data was swapped to Lucide.
const _LSvg = (p, children) => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>{children}</svg>
);
const Icon = {
  // lucide: phone
  phone: (p = {}) => _LSvg(p, <path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384" />),
  // lucide: camera
  camera: (p = {}) => _LSvg(p, <>
    <path d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" />
    <circle cx="12" cy="13" r="3" />
  </>),
  // lucide: arrow-right
  arrow: (p = {}) => _LSvg(p, <><path d="M5 12h14" /><path d="m12 5 7 7-7 7" /></>),
  // lucide: message-square (legacy key 'line' — generic chat bubble only)
  line: (p = {}) => _LSvg(p, <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" />),
  // lucide: check
  check: (p = {}) => _LSvg(p, <path d="M20 6 9 17l-5-5" />),
  // lucide: map-pin
  pin: (p = {}) => _LSvg(p, <>
    <path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" />
    <circle cx="12" cy="10" r="3" />
  </>),
  // lucide: shield
  shield: (p = {}) => _LSvg(p, <path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />),
  // lucide: clock
  clock: (p = {}) => _LSvg(p, <><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></>),
  // lucide: message-square
  chat: (p = {}) => _LSvg(p, <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" />),
  // lucide: triangle-alert
  alert: (p = {}) => _LSvg(p, <>
    <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
    <path d="M12 9v4" /><path d="M12 17h.01" />
  </>),
  // lucide: cloud-rain
  rain: (p = {}) => _LSvg(p, <>
    <path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" />
    <path d="M16 14v6" /><path d="M8 14v6" /><path d="M12 16v6" />
  </>),
  // lucide: house
  home: (p = {}) => _LSvg(p, <>
    <path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" />
    <path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
  </>),
  // custom (Lucide-toned): simple gable roof + eaves line — for 屋根 (no Lucide equivalent)
  roof: (p = {}) => _LSvg(p, <>
    <path d="M3 12.5 12 5l9 7.5" />
    <path d="M5.5 11.5V15a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1v-3.5" />
  </>),
  // custom (Lucide-toned): drone — for services whose CMS name contains ドローン
  drone: (p = {}) => _LSvg(p, <>
    <path d="M3 5.5 h6.4 M14.6 5.5 h6.4" />
    <path d="M6.2 5.5 v2.8 M17.8 5.5 v2.8" />
    <rect x="8.2" y="8.3" width="7.6" height="5.9" rx="1.9" />
    <path d="M9.8 14.2 L7.8 19.5 M14.2 14.2 L16.2 19.5" />
  </>),
  // lucide: brick-wall
  brick: (p = {}) => _LSvg(p, <>
    <rect width="18" height="18" x="3" y="3" rx="2" />
    <path d="M12 9v6" /><path d="M16 15v6" /><path d="M16 3v6" />
    <path d="M3 15h18" /><path d="M3 9h18" />
    <path d="M8 15v6" /><path d="M8 3v6" />
  </>),
  // custom (Lucide-toned): house outline + crack — for 外壁のヒビ
  houseCrack: (p = {}) => _LSvg(p, <>
    <path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
    <path d="m12 9-1.5 3 2.5 1-2 4" />
  </>),
  // lucide: droplet
  drop: (p = {}) => _LSvg(p, <path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z" />),
  // lucide: bath — for 内装・水回り
  bath: (p = {}) => _LSvg(p, <>
    <path d="M10 4 8 6" /><path d="M17 19v2" /><path d="M2 12h20" /><path d="M7 19v2" />
    <path d="M9 5 7.621 3.621A2.121 2.121 0 0 0 4 5v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5" />
  </>),
  // lucide: fence — for 玄関・外構
  fence: (p = {}) => _LSvg(p, <>
    <path d="M4 3 2 5v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z" />
    <path d="M6 8h4" /><path d="M6 18h4" />
    <path d="m12 3-2 2v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z" />
    <path d="M14 8h4" /><path d="M14 18h4" />
    <path d="m20 3-2 2v15c0 .6.4 1 1 1h2c.6 0 1-.4 1-1V5Z" />
  </>),
  // lucide: house-plus — for 住まい全体の相談
  housePlus: (p = {}) => _LSvg(p, <>
    <path d="M12.35 21H5a2 2 0 0 1-2-2v-9a2 2 0 0 1 .71-1.53l7-6a2 2 0 0 1 2.58 0l7 6A2 2 0 0 1 21 10v2.35" />
    <path d="M14.8 12.4A1 1 0 0 0 14 12h-4a1 1 0 0 0-1 1v8" />
    <path d="M15 18h6" /><path d="M18 15v6" />
  </>),
  // lucide: wrench
  wrench: (p = {}) => _LSvg(p, <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" />),
};

// Smartlife logo as SVG so it adapts to dark/light surfaces without needing a 2nd file
function LogoMark({ color = '#e87437', size = 22 }) {
  return (
    <svg viewBox="0 0 32 22" width={size * 1.45} height={size} fill="none" stroke={color} strokeWidth="2.2" strokeLinejoin="round" strokeLinecap="round">
      <path d="M3 14 L16 3 L29 14" />
      <path d="M9 14 L9 19 M14 14 L14 19 M19 14 L19 19 M24 14 L24 19" stroke={color} strokeWidth="1.6" />
    </svg>
  );
}

// Brand mark from the supplied Smartlife logo package.
function BrandMark({ size = 44, tone = 'green' }) {
  const src = tone === 'orange' ? ASSETS.logoOrange : tone === 'mono' ? ASSETS.logoBlack : ASSETS.logoGreen;
  const [failed, setFailed] = React.useState(false);
  React.useEffect(() => { setFailed(false); }, [src]);
  if (failed) {
    return <span aria-hidden="true" style={{ width: size, height: size, display: 'block' }} />;
  }
  return (
    <img
      src={src}
      alt={COMPANY.name}
      decoding="async"
      onError={() => setFailed(true)}
      style={{ width: size, height: size, display: 'block', objectFit: 'contain' }}
    />
  );
}

// CMSの「ロゴ：通常表示（logo）」が既定値以外に設定されているときだけ、その画像を
// 横長ロックアップとして表示する。未設定・既定値・読込失敗時は fallback（従来の
// マーク+テキスト構成）をそのまま表示する。既定値の文字列は cms/default-content.js
// と _A('logo', …) の既定に一致させること。
const BRAND_LOGO_DEFAULT = 'assets/logo-smartlife.png';
function BrandLockup({ height = 40, maxWidth = 230, fallback = null }) {
  const custom = typeof ASSETS.logo === 'string' && ASSETS.logo.trim() && ASSETS.logo !== BRAND_LOGO_DEFAULT
    ? ASSETS.logo : null;
  const [failed, setFailed] = React.useState(false);
  React.useEffect(() => { setFailed(false); }, [custom]);
  if (!custom || failed) return fallback;
  return (
    <img
      src={custom}
      alt={COMPANY.name}
      decoding="async"
      onError={() => setFailed(true)}
      style={{
        height, width: 'auto', maxWidth, display: 'block', objectFit: 'contain',
        // JPGロゴのごく薄いグレー背景を白ヘッダーに馴染ませる（multiplyは純白面での保険、
        // brightnessで #f7f5f2 程度の背景を白へ持ち上げる。ロゴ本体の色への影響は4%弱で知覚不能）
        mixBlendMode: 'multiply', filter: 'brightness(1.045)',
      }}
    />
  );
}

// Common steps for the "相談から完工まで" section — same script, each LP styles it
const FLOW_STEPS = [
  { n: '01', title: 'お問い合わせ・ご相談', body: 'まずはお電話またはメールフォームよりお気軽にご相談ください。' },
  { n: '02', title: '現地調査・診断', body: '屋根や外壁など、気になる箇所を専門スタッフが実際に確認いたします。' },
  { n: '03', title: 'お見積り・ご提案', body: '撮影した写真をもとに、必要な工事に絞って分かりやすくご説明いたします。' },
  { n: '04', title: '施工・完工', body: 'ご納得いただいた内容で工事を進めます。完工時はお客さまと一緒に最終確認を行います。' },
  { n: '05', title: 'アフターサポート', body: '工事完了後も、工事箇所だけでなくアフターサポートいたします。気になることやお困りごとがあれば、いつでもお気軽にご相談ください。※定期点検等で工事後もご安心いただけます' },
];

const CERTIFICATIONS = [
  {
    label: '雨漏り診断士資格',
    name: '雨漏り診断士',
    number: 'NPO法人 雨漏り診断士協会／登録番号 2019245',
    icon: 'drop',
  },
];

// Knowledge / お役立ち情報 — three articles, same set for every LP
const KNOWLEDGE = [
  { tag: '雨漏り', photo: ASSETS.knowLeakWatercolor, title: '雨漏りに気づいたら、まず確認すること',     blurb: '天井のシミ、雨漏りの音、サッシまわりのにじみ。慌てて屋根に上がる前に、まずは落ち着いてこちらをチェックしてください。' },
  { tag: '屋根',   photo: ASSETS.knowRoofWatercolor, title: '屋根の種類とメンテナンス時期の目安',       blurb: '瓦・スレート・金属屋根。屋根材ごとの特徴と、適切な補修・改修のタイミングをまとめました。' },
  { tag: '外壁',   photo: ASSETS.knowWallWatercolor, title: '外壁のひび割れ・チョーキング・剥がれの見方', blurb: '壁のひびや白い粉、塗装の剥がれ。住まいからのサインを、プロに相談する前にセルフチェックしてみましょう。' },
];

window.SL = {
  ASSETS, COPY, COMPANY, SERVICES, FLOW_STEPS, CERTIFICATIONS, KNOWLEDGE,
  PhotoPlaceholder, CoverImg, Icon, LogoMark, BrandMark, BrandLockup, copyText, rawCopyValue,
  slHref, slServiceHref, slArticleHref, slCaseHref, slNavHref, dialablePhone, hasText, hasImageRef,
};
