[0, 767],
'tablet' => [768, 1023],
'desktop' => [1024, PHP_INT_MAX],
'portable' => [0, 1023],
];
/**
* 템플릿 제공 컴포넌트 매핑 (seo-config.json의 component_map)
*/
private array $componentMap = [];
/**
* 템플릿 제공 렌더 모드 정의 (seo-config.json의 render_modes)
*/
private array $renderModes = [];
/**
* 셀프 클로징 태그 목록 (seo-config.json의 self_closing)
*/
private array $selfClosing = [];
/**
* 텍스트 추출 대상 props 키 목록 (seo-config.json의 text_props로 오버라이드 가능)
*/
private array $textProps = ['text', 'label', 'value', 'title'];
/**
* React→HTML 속성명 매핑 (seo-config.json의 attr_map으로 오버라이드 가능)
*/
private array $attrMap = [
'className' => 'class',
'htmlFor' => 'for',
];
/**
* 허용된 HTML 속성 목록 (seo-config.json의 allowed_attrs로 오버라이드 가능)
*/
private array $allowedAttrs = [
'class', 'id', 'href', 'src', 'alt', 'title', 'name', 'type',
'placeholder', 'for', 'target', 'rel', 'width', 'height',
'role', 'aria-label', 'aria-describedby', 'data-testid', 'style',
];
/**
* SEO 변수 (meta.seo.vars에서 해석된 값, format 모드에서 사용)
*/
private array $seoVars = [];
/**
* _global 표현식 해석 콜백 (SeoRenderer에서 주입)
*/
private ?\Closure $globalResolver = null;
/**
* fields 렌더 모드 실행 중 임시 참조 (renderFieldEntry에서 $t: 번역 해석용)
*/
private ?ExpressionEvaluator $fieldsEvaluator = null;
/**
* fields 렌더 모드 실행 중 임시 데이터 컨텍스트
*/
private array $fieldsContext = [];
/**
* 사용자 작성 HTML 정화기 (raw 렌더 모드에서 지연 생성)
*/
private ?HtmlSanitizer $htmlSanitizer = null;
/**
* `value` prop 을 텍스트로 승격하지 않는 태그 목록
*
* 폼 컨트롤의 `value` 는 현재 선택값(속성)이지 화면에 보이는 글자가 아닙니다.
* React 는 `