<?php declare(strict_types=1); ?>
<!-- ═══════════════════════════════════════════════════════════════════
     Output & Build Settings — in-app Guide
     Self-contained (own markup + styles + open/close/scrollspy script).
     Opened by any element with [data-ob-help-open]; closed by scrim,
     the × button, or Escape. Never touches the page's own state.
     ══════════════════════════════════════════════════════════════════ -->
<style>
    .obh-scrim { position:fixed; inset:0; z-index:10050; background:rgba(15,23,42,.55);
        backdrop-filter:blur(3px); display:none; opacity:0; transition:opacity .18s; }
    .obh-scrim.open { display:block; opacity:1; }
    .obh-modal { position:fixed; z-index:10051; top:3vh; bottom:3vh; left:50%;
        width:min(1060px, 94vw); transform:translateX(-50%) translateY(14px);
        background:#fff; border-radius:16px; box-shadow:0 32px 80px rgba(2,6,23,.5);
        display:flex; flex-direction:column; overflow:hidden; opacity:0;
        transition:transform .2s, opacity .2s; }
    .obh-scrim.open .obh-modal { transform:translateX(-50%) translateY(0); opacity:1; }

    .obh-head { flex:0 0 auto; display:flex; align-items:center; gap:14px;
        padding:16px 22px; border-bottom:1px solid #e2e8f0;
        background:linear-gradient(120deg,#3730a3,#4f46e5 55%,#7c3aed); color:#fff; }
    .obh-head .obh-badge { width:40px; height:40px; border-radius:11px; flex:0 0 40px;
        display:flex; align-items:center; justify-content:center; font-size:20px;
        background:rgba(255,255,255,.16); }
    .obh-head h2 { margin:0; font-size:17px; font-weight:800; letter-spacing:-.01em; }
    .obh-head p  { margin:2px 0 0; font-size:12px; opacity:.82; }
    .obh-close { margin-left:auto; width:34px; height:34px; border-radius:9px; border:0;
        background:rgba(255,255,255,.14); color:#fff; font-size:18px; cursor:pointer;
        display:flex; align-items:center; justify-content:center; transition:.15s; }
    .obh-close:hover { background:rgba(255,255,255,.28); }

    .obh-body { flex:1; min-height:0; display:grid; grid-template-columns:236px 1fr; }
    .obh-toc { border-right:1px solid #e2e8f0; background:#f8fafc; overflow-y:auto; padding:14px 8px 24px; }
    .obh-toc-group { font-size:9.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
        color:#94a3b8; padding:14px 14px 5px; }
    .obh-toc a { display:flex; align-items:center; gap:9px; padding:7px 14px; border-radius:8px;
        margin:1px 6px; font-size:12.5px; color:#475569; text-decoration:none; cursor:pointer;
        border-left:3px solid transparent; }
    .obh-toc a:hover { background:#eef2ff; color:#4338ca; }
    .obh-toc a.active { background:#eef2ff; color:#4338ca; font-weight:700; border-left-color:#6366f1; }
    .obh-toc a i { font-size:14px; width:16px; flex:0 0 16px; color:#818cf8; }

    .obh-content { position:relative; overflow-y:auto; padding:8px 40px 80px; scroll-behavior:smooth; color:#1e293b; }
    .obh-content section { padding-top:26px; }
    .obh-content h3 { font-size:21px; font-weight:800; letter-spacing:-.02em; margin:6px 0 4px;
        color:#0f172a; display:flex; align-items:center; gap:10px; }
    .obh-content h3 .num { font-size:12px; font-weight:800; color:#4338ca; background:#eef2ff;
        border-radius:8px; padding:3px 9px; }
    .obh-content h4 { font-size:14.5px; font-weight:800; margin:22px 0 6px; color:#312e81; }
    .obh-content p  { font-size:13.5px; line-height:1.66; color:#334155; margin:8px 0; }
    .obh-content ul, .obh-content ol { font-size:13.5px; line-height:1.66; color:#334155;
        margin:8px 0; padding-left:22px; }
    .obh-content li { margin:4px 0; }
    .obh-lead { font-size:15px; line-height:1.65; color:#475569; }
    .obh-content code { font-family:ui-monospace,Menlo,Consolas,monospace; font-size:12px;
        background:#eef2ff; color:#4338ca; padding:1.5px 6px; border-radius:5px; }

    .obh-callout { display:flex; gap:12px; padding:13px 16px; border-radius:11px; margin:14px 0;
        font-size:13px; line-height:1.6; }
    .obh-callout i { font-size:17px; flex:0 0 auto; margin-top:1px; }
    .obh-callout.tip  { background:#ecfdf5; color:#065f46; } .obh-callout.tip i { color:#059669; }
    .obh-callout.warn { background:#fffbeb; color:#854d0e; } .obh-callout.warn i { color:#d97706; }
    .obh-callout.info { background:#eff6ff; color:#1e40af; } .obh-callout.info i { color:#2563eb; }
    .obh-callout.moved{ background:#f5f3ff; color:#5b21b6; } .obh-callout.moved i { color:#7c3aed; }

    .obh-table { width:100%; border-collapse:collapse; margin:12px 0; font-size:12.5px; }
    .obh-table th { text-align:left; font-weight:800; color:#475569; background:#f8fafc;
        padding:8px 11px; border-bottom:2px solid #e2e8f0; font-size:11px; text-transform:uppercase;
        letter-spacing:.03em; }
    .obh-table td { padding:8px 11px; border-bottom:1px solid #f1f5f9; vertical-align:top; color:#334155; }
    .obh-table td code { white-space:nowrap; }
    .obh-table tr:hover td { background:#f8faff; }

    .obh-foot { margin-top:34px; padding-top:16px; border-top:1px solid #e2e8f0;
        font-size:12px; color:#94a3b8; }

    @media (max-width:760px) {
        .obh-body { grid-template-columns:1fr; }
        .obh-toc { display:none; }
        .obh-content { padding:8px 20px 60px; }
    }
</style>

<div class="obh-scrim" id="obHelpScrim" aria-hidden="true">
  <div class="obh-modal pp-legacy-guide" role="dialog" aria-modal="true" aria-label="Output and Build guide">
    <div class="obh-head">
      <div class="obh-badge"><i class="bi bi-box-arrow-up-right"></i></div>
      <div>
        <h2>Output &amp; Build — Guide</h2>
        <p>Control how your project is generated, optimized, and packaged for release.</p>
      </div>
      <button class="obh-close" id="obHelpClose" title="Close (Esc)" aria-label="Close"><i class="bi bi-x-lg" aria-hidden="true"></i></button>
    </div>

    <div class="obh-body">
      <nav class="obh-toc" id="obHelpToc">
        <div class="obh-toc-group">Overview</div>
        <a data-goto="o-what"><i class="bi bi-stars"></i> What this module does</a>
        <a data-goto="o-moved"><i class="bi bi-signpost-split"></i> Where did FTP &amp; DB go?</a>

        <div class="obh-toc-group">General</div>
        <a data-goto="o-target"><i class="bi bi-folder2-open"></i> Output target</a>
        <a data-goto="o-behavior"><i class="bi bi-hammer"></i> Build behavior &amp; presets</a>
        <a data-goto="o-info"><i class="bi bi-clipboard-data"></i> Build information</a>

        <div class="obh-toc-group">Optimization</div>
        <a data-goto="o-assets"><i class="bi bi-lightning-charge"></i> Asset optimization</a>
        <a data-goto="o-doc"><i class="bi bi-file-earmark-code"></i> Document output</a>

        <div class="obh-toc-group">Advanced</div>
        <a data-goto="o-hooks"><i class="bi bi-terminal"></i> Build hooks</a>
        <a data-goto="o-files"><i class="bi bi-tools"></i> Generated file options</a>
        <a data-goto="o-extra"><i class="bi bi-file-plus"></i> Additional files</a>

        <div class="obh-toc-group">Reference</div>
        <a data-goto="o-faq"><i class="bi bi-question-circle"></i> Best practices &amp; FAQ</a>
      </nav>

      <div class="obh-content" id="obHelpContent">

        <section id="o-what">
          <h3><span class="num">01</span> What this module does</h3>
          <p class="obh-lead">The <b>Output &amp; Build Settings</b> module defines <b>how</b> your project turns into a
          real, runnable application — where files land on disk, how the app addresses itself by URL, how assets are
          optimized, and what extra files are emitted.</p>
          <p>Settings here are read by the <b>Build</b> step (the <b>Build</b> button in the top bar, or the
          <b>Finished</b> screen). Everything you change is <b>saved automatically</b> — watch the pill in the toolbar:
          it shows <i class="bi bi-cloud-arrow-up"></i> <b>Unsaved changes</b> → <i class="bi bi-arrow-repeat"></i>
          <b>Saving</b> → <i class="bi bi-cloud-check"></i> <b>Saved</b>.</p>
          <div class="obh-callout info"><i class="bi bi-info-circle-fill"></i>
            <div>Nothing here modifies your live app directly. These are <b>build-time</b> instructions —
            they take effect the next time you build.</div></div>
        </section>

        <section id="o-moved">
          <h3><span class="num">02</span> Where did FTP &amp; database deployment go?</h3>
          <p>Server upload and live-database configuration used to live on a <i>Deployment</i> tab here. They now
          have a dedicated home: the <b>Deploy</b> module — a full FTP / FTPS / SFTP client.</p>
          <div class="obh-callout moved"><i class="bi bi-signpost-split-fill"></i>
            <div><b>Looking for FTP upload or live DB connections?</b> Open the <b>Deploy</b> module from the
            project sidebar (<i class="bi bi-cloud-arrow-up"></i>). It manages encrypted connection profiles,
            browses the remote server, uploads changed-files-only, and injects a live database config into the
            <i>uploaded</i> app without ever touching your local settings.</div></div>
          <p>This keeps Output focused on <b>generating</b> the app, and Deploy focused on <b>shipping</b> it.</p>
        </section>

        <section id="o-target">
          <h3><span class="num">03</span> Output target</h3>
          <p>Three fields under <b>General → Output Target</b> tell the builder where the app goes and how it is
          addressed:</p>
          <table class="obh-table">
            <thead><tr><th>Field</th><th>What it means</th></tr></thead>
            <tbody>
              <tr><td><b>Output Directory</b></td><td>Absolute path (<code>/var/www/html/myapp</code>) or a path relative to the app root (<code>../output</code>) where generated files are written. The badge beside it shows whether that path <b>exists</b> and is <b>writable</b>.</td></tr>
              <tr><td><b>Base URL</b></td><td>The public base of the site (<code>/myapp</code> or <code>https://example.com/app</code>), with <b>no trailing slash</b>. Generated routes and asset links are built from this.</td></tr>
              <tr><td><b>Preview URL</b></td><td>Where the <b>Preview</b> action opens the running app in your browser.</td></tr>
            </tbody>
          </table>
          <div class="obh-callout tip"><i class="bi bi-lightbulb-fill"></i>
            <div>Use the <i class="bi bi-folder2-open"></i> button for common path suggestions. Leave the directory
            blank and the builder defaults to <code>output/&lt;project&gt;</code> under the app root.</div></div>
        </section>

        <section id="o-behavior">
          <h3><span class="num">04</span> Build behavior &amp; presets</h3>
          <h4>Environment presets</h4>
          <p>The <b>Development</b> and <b>Production</b> buttons apply sensible defaults across the Optimization and
          Advanced tabs in one click — you can still fine-tune any individual switch afterwards:</p>
          <table class="obh-table">
            <thead><tr><th>Setting</th><th>Development</th><th>Production</th></tr></thead>
            <tbody>
              <tr><td>Compress JS / CSS / HTML</td><td>off — readable output</td><td>on — smallest files</td></tr>
              <tr><td>Asset versioning &amp; inline minify</td><td>off</td><td>on</td></tr>
              <tr><td>Error reporting</td><td>show all errors</td><td>log only</td></tr>
              <tr><td>Debug mode</td><td>on</td><td>off</td></tr>
            </tbody>
          </table>
          <h4>Build type &amp; clean</h4>
          <ul>
            <li><b>Full Build</b> regenerates the entire app — the safe default.</li>
            <li><b>Incremental</b> only rewrites changed files (faster, assumes prior output exists).</li>
            <li><b>Clean output directory before build</b> wipes old generated files first for a pristine result.
              Leave off when doing incremental builds.</li>
          </ul>
        </section>

        <section id="o-info">
          <h3><span class="num">05</span> Build information</h3>
          <p>The <b>Build Information</b> card shows <b>real</b> data — not placeholders:</p>
          <ul>
            <li><b>Last Build</b>, <b>Files Generated</b>, and <b>Build Duration</b> come from your most recent
              successful build.</li>
            <li><b>Output Size</b> and the status badge are measured <b>live</b> from the output directory each time
              the card loads.</li>
          </ul>
          <p>Press <i class="bi bi-arrow-clockwise"></i> to refresh, or <b>Go to Build &amp; Finish</b> to run a build.</p>
          <div class="obh-callout info"><i class="bi bi-info-circle-fill"></i>
            <div>A <span style="color:#b45309;font-weight:700">not writable</span> badge means the server can't write
            there — fix the folder permissions before building.</div></div>
        </section>

        <section id="o-assets">
          <h3><span class="num">06</span> Asset optimization</h3>
          <p>Each switch shrinks or cache-busts generated assets:</p>
          <ul>
            <li><b>Compress JavaScript / CSS / HTML</b> — minify output to cut file size and speed up loads.</li>
            <li><b>Asset versioning</b> — append <code>?v=hash</code> to CSS/JS URLs so browsers always fetch the
              latest file after an update (no more stale caches).</li>
            <li><b>Minify inline scripts &amp; styles</b> — compress <code>&lt;script&gt;</code> /
              <code>&lt;style&gt;</code> blocks embedded in pages.</li>
          </ul>
          <div class="obh-callout tip"><i class="bi bi-lightbulb-fill"></i>
            <div>Turn compression <b>off</b> while developing so generated code stays readable for debugging, then
            flip the <b>Production</b> preset before you ship.</div></div>
        </section>

        <section id="o-doc">
          <h3><span class="num">07</span> Document output</h3>
          <p><b>HTML Doctype</b> and <b>Character Encoding</b> are written into every generated page. Stick with
          <b>HTML5</b> and <b>UTF-8</b> unless you have a specific legacy requirement.</p>
        </section>

        <section id="o-hooks">
          <h3><span class="num">08</span> Build hooks</h3>
          <p>Run a command automatically around each build:</p>
          <ul>
            <li><b>Pre-Build Command</b> — runs <i>before</i> generation (e.g. clear a cache).</li>
            <li><b>Post-Build Command</b> — runs <i>after</i> generation (e.g. set permissions, notify a service).</li>
          </ul>
          <div class="obh-callout warn"><i class="bi bi-exclamation-triangle-fill"></i>
            <div>Hooks execute with the web server's privileges. Only enter commands you fully trust — treat this like
            a shell prompt on the server.</div></div>
        </section>

        <section id="o-files">
          <h3><span class="num">09</span> Generated file options</h3>
          <table class="obh-table">
            <thead><tr><th>Option</th><th>Purpose</th></tr></thead>
            <tbody>
              <tr><td><b>File Permissions</b></td><td>Octal mode for generated files. Use the <b>Presets</b> menu — <code>0644</code> suits most shared hosts.</td></tr>
              <tr><td><b>Line Endings</b></td><td><code>LF</code> for Unix/macOS servers, <code>CRLF</code> for Windows.</td></tr>
              <tr><td><b>Version Label</b></td><td>A version string embedded in generated metadata (e.g. <code>1.0.0</code>).</td></tr>
              <tr><td><b>Error Reporting</b></td><td>How the generated app surfaces PHP errors — <b>Production</b> logs silently.</td></tr>
              <tr><td><b>Debug mode</b></td><td>Verbose runtime diagnostics. <b>Never</b> ship this enabled.</td></tr>
            </tbody>
          </table>
        </section>

        <section id="o-extra">
          <h3><span class="num">10</span> Additional files</h3>
          <p>Optionally emit server &amp; SEO helper files alongside the app:</p>
          <ul>
            <li><b><code>.htaccess</code></b> — Apache URL rewriting &amp; security rules.</li>
            <li><b><code>web.config</code></b> — the IIS equivalent for Windows servers.</li>
            <li><b><code>robots.txt</code></b> — crawler directives for search engines.</li>
          </ul>
          <div class="obh-callout tip"><i class="bi bi-lightbulb-fill"></i>
            <div>Enable <code>.htaccess</code> for typical Apache/cPanel hosting so clean URLs work out of the box.</div></div>
        </section>

        <section id="o-faq">
          <h3><span class="num">11</span> Best practices &amp; FAQ</h3>
          <h4>Do I have to click Save?</h4>
          <p>No — every change auto-saves within a second. The central <b>Save</b> button and closing the tab both
          flush pending changes too.</p>
          <h4>When do these settings take effect?</h4>
          <p>On the next <b>Build</b>. Output settings are instructions the builder reads; they never alter a
          previously built app until you rebuild.</p>
          <h4>My build info says "Never" — is something wrong?</h4>
          <p>No, it just means this project hasn't been built yet. Run a build from <b>Build &amp; Finish</b> and the
          card fills in.</p>
          <h4>How do I actually upload to my live server?</h4>
          <p>Use the <b>Deploy</b> module — see <a style="color:#4338ca;font-weight:600;cursor:pointer" data-goto-inline="o-moved">section 02</a>.</p>
          <div class="obh-foot"><?= htmlspecialchars(\PpPhp\Core\Brand::name()) ?> Output &amp; Build — generate once, ship anywhere.
          Press <kbd>Esc</kbd> or click outside to close.</div>
        </section>

      </div>
    </div>
  </div>
</div>

<script>
(function () {
    var scrim   = document.getElementById('obHelpScrim');
    var closeB  = document.getElementById('obHelpClose');
    var toc     = document.getElementById('obHelpToc');
    var content = document.getElementById('obHelpContent');
    if (!scrim) return;

    function open()  { scrim.classList.add('open'); scrim.setAttribute('aria-hidden', 'false');
                       document.body.style.overflow = 'hidden'; }
    function close() { scrim.classList.remove('open'); scrim.setAttribute('aria-hidden', 'true');
                       document.body.style.overflow = ''; }

    document.addEventListener('click', function (e) {
        var t = e.target.closest('[data-ob-help-open]');
        if (t) { e.preventDefault(); open(); }
        var inline = e.target.closest('[data-goto-inline]');
        if (inline) { goTo(inline.dataset.gotoInline); }
    });
    closeB.addEventListener('click', close);
    scrim.addEventListener('click', function (e) { if (e.target === scrim) close(); });
    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape' && scrim.classList.contains('open')) { e.stopPropagation(); close(); }
    });

    var links = Array.prototype.slice.call(toc.querySelectorAll('a[data-goto]'));
    function setActive(id) {
        links.forEach(function (a) { a.classList.toggle('active', a.dataset.goto === id); });
    }
    function goTo(id) {
        var el = document.getElementById(id);
        if (el) { content.scrollTo({ top: el.offsetTop - 8, behavior: 'smooth' }); setActive(id); }
    }
    links.forEach(function (a) { a.addEventListener('click', function () { goTo(a.dataset.goto); }); });

    var sections = links.map(function (a) { return document.getElementById(a.dataset.goto); }).filter(Boolean);
    function spy() {
        if (content.scrollTop + content.clientHeight >= content.scrollHeight - 4) {
            setActive(sections[sections.length - 1].id); return;
        }
        var y = content.scrollTop + 80, cur = sections[0];
        for (var i = 0; i < sections.length; i++) { if (sections[i].offsetTop <= y) cur = sections[i]; }
        if (cur) setActive(cur.id);
    }
    content.addEventListener('scroll', spy);
    spy();

    window.PpOutputHelp = { open: open, close: close };
})();
</script>
