// @ts-check
(()=>{
  'use strict';
  const DATA=window.IUS_TEMPLATE_DATA||{};
  const root=document.documentElement;
  const validPalettes=["signal-noir"];
  const validAppearances=["dark"];
  let savedLocale=null;try{savedLocale=localStorage.getItem('ius-template-locale-v1')}catch(_){}
  const routeLocale=root.dataset.locale;
  const state={
    palette:validPalettes.includes(root.dataset.palette||'')?root.dataset.palette:"signal-noir",
    appearance:validAppearances.includes(root.dataset.appearance||'')?root.dataset.appearance:"dark",
    locale:routeLocale==='ja'?'ja':routeLocale==='en'?'en':savedLocale==='ja'?'ja':'en',
    motion:DATA.siteConfig?.theme?.motion!==false,
    sensorMotion:false,
    activeProject:0,
    activePost:null
  };
  const listeners=new Set();
  const api=window.IUS_TEMPLATE={data:DATA,state,modules:{},utils:{}};
  api.utils.$=(selector,scope=document)=>scope.querySelector(selector);
  api.utils.$$=(selector,scope=document)=>Array.from(scope.querySelectorAll(selector));
  api.utils.escapeHtml=value=>String(value).replace(/[&<>'"]/g,char=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[char]));
  api.utils.local=(value,locale=state.locale)=>value&&typeof value==='object'?(value[locale]??value.en??''):value??'';
  api.utils.formatDate=(iso,locale=state.locale,opts={dateStyle:'long'})=>new Intl.DateTimeFormat(locale==='ja'?'ja-JP':'en-GB',opts).format(new Date(`${iso}T12:00:00Z`));
  api.utils.readingTime=(post,locale=state.locale)=>{
    const blocks=post?.body?.[locale]||post?.body?.en||[];
    const chars=blocks.reduce((sum,b)=>sum+String(b.text||'').length,0);
    return Math.max(1,Math.ceil(chars/(locale==='ja'?500:1000)));
  };
  api.utils.canonicalPost=slug=>new URL(`posts/${slug}/`,DATA.siteConfig?.brand?.url||location.href).href;
  api.utils.openDialog=(dialog,trigger)=>{if(!dialog)return;dialog.__trigger=trigger||document.activeElement;if(typeof dialog.showModal==='function')dialog.showModal();else dialog.setAttribute('open','');document.body.classList.add('dialog-open')};
  api.utils.closeDialog=dialog=>{if(!dialog)return;if(typeof dialog.close==='function'&&dialog.open)dialog.close();else dialog.removeAttribute('open');document.body.classList.remove('dialog-open');const t=dialog.__trigger;if(t&&typeof t.focus==='function')requestAnimationFrame(()=>t.focus({preventScroll:true}))};
  api.utils.copy=async text=>{try{await navigator.clipboard.writeText(text);return true}catch(_){const area=document.createElement('textarea');area.value=text;area.style.position='fixed';area.style.opacity='0';document.body.append(area);area.select();const ok=document.execCommand('copy');area.remove();return ok}};
  api.setState=patch=>{Object.assign(state,patch);listeners.forEach(fn=>fn(state,patch));document.dispatchEvent(new CustomEvent('ius:statechange',{detail:{state,patch}}))};
  api.subscribe=fn=>{listeners.add(fn);return()=>listeners.delete(fn)};
})();
