/*
* NSY PHP Framework — base website theme.
*
* Brand palette taken from the NSY logo:
*   - Biru Tua  (dominant, letterforms)      : #1D7BBA
*   - Biru Muda (accent, diagonal cross line): #5CB4F5
*
* Everything else is derived from those two colours so the whole site stays
* on-brand. This file is the single stylesheet for the whole site: base
* layout, the documentation index (Index_Welcome), the documentation viewer
* (Index_Docs) and the HMVC landing page (Index_Hello). Views carry markup
* only — no inline <style>.
*
* The cross-browser base styles below are the result of much research by
* Nicolas Gallagher, Jonathan Neal, Kroc Camen, and the H5BP dev community.
*/

/* ==========================================================================
  NSY brand palette (logo colours) — single source of truth
  ========================================================================== */

:root {
    /* Core logo colours */
    --nsy-primary: #1D7BBA;
    /* Biru Tua  — dominant (letterforms) */
    --nsy-accent: #5CB4F5;
    /* Biru Muda — accent (diagonal cross line) */

    /* Derived shades */
    --nsy-primary-dark: #155F92;
    /* hover / pressed */
    --nsy-primary-deep: #0F4468;
    /* strong heading / ink */
    --nsy-accent-dark: #3D9BE8;
    /* accent hover */
    --nsy-accent-soft: #EAF5FE;
    /* tinted surface */
    --nsy-accent-softer: #F4FAFF;
    /* faint surface */

    /* Neutrals tinted toward the logo blue */
    --nsy-ink: #133A56;
    /* headings */
    --nsy-body: #44576B;
    /* body copy */
    --nsy-muted: #7C93A6;
    /* secondary text */
    --nsy-line: #DCE9F5;
    /* hairline borders */

    /* Code surfaces */
    --nsy-code-bg: #0C2B41;
    --nsy-code-fg: #E4F1FB;

    /* Brand gradient — echoes the logo slashes */
    --nsy-gradient: linear-gradient(90deg, var(--nsy-primary), var(--nsy-accent));

    /* Elevation */
    --nsy-shadow: 0 8px 24px rgba(29, 123, 186, .14);
    --nsy-shadow-strong: 0 6px 20px rgba(29, 123, 186, .35);

    /* Surfaces & accents (themeable) */
    --nsy-page: #FFFFFF;
    --nsy-surface: #FFFFFF;
    --nsy-on-primary: #FFFFFF;
    --nsy-mark: #FEF08A;
    --nsy-mark-fg: #3B2F00;
    --nsy-focus-ring: rgba(92, 180, 245, .22);

    color-scheme: light;
}

/* Dark theme. Applied before first paint by the header script from
   localStorage / the OS setting, and toggled by the button in the site header.
   Only the tokens change — every rule already reads them, so the whole site
   flips at once. */
[data-theme="dark"] {
    color-scheme: dark;

    --nsy-primary: #4FA8E0;
    --nsy-primary-dark: #6FBBEC;
    --nsy-primary-deep: #DCEDFB;
    --nsy-accent: #5CB4F5;
    --nsy-accent-dark: #8FCBF8;
    --nsy-accent-soft: #123A57;
    --nsy-accent-softer: #0F2C43;

    --nsy-ink: #E8F2FA;
    --nsy-body: #BFD0DE;
    --nsy-muted: #8DA6BA;
    --nsy-line: #234259;

    --nsy-code-bg: #061520;
    --nsy-code-fg: #D9EBF8;

    --nsy-shadow: 0 8px 24px rgba(0, 0, 0, .55);
    --nsy-shadow-strong: 0 6px 20px rgba(0, 0, 0, .6);

    --nsy-page: #0B1B28;
    --nsy-surface: #102A3D;
    --nsy-on-primary: #06131C;
    --nsy-mark: #5B4A12;
    --nsy-mark-fg: #F3E9B8;
    --nsy-focus-ring: rgba(92, 180, 245, .35);
}

/* Category accents, dark variants (light values live further down). */
[data-theme="dark"] .nsy-cat[data-cat="getting-started"] {
    --cat: #5FB0E8;
    --cat-soft: #12314A;
}

[data-theme="dark"] .nsy-cat[data-cat="core"] {
    --cat: #7FC2F0;
    --cat-soft: #133A57;
}

[data-theme="dark"] .nsy-cat[data-cat="reference"] {
    --cat: #A0B6C8;
    --cat-soft: #1B2F40;
}

/* ==========================================================================
  Base styles: opinionated defaults
  ========================================================================== */

html {
    height: 100%;
    box-sizing: border-box;
}

/* Border-box everywhere: padding/border stay inside declared widths, so
   full-width shells (e.g. .nsy-page) never overflow the viewport. */
*,
*::before,
*::after {
    box-sizing: inherit;
}

body,
h1,
h2,
h3,
h4,
h5 {
    font-family: 'Lato', sans-serif !important;
}

/*
* Styling for Sticky Footer with Flexbox
*/
body {
    display: flex;
    flex-direction: column;
    height: 100vh;
    /* Avoid the IE 10-11 `min-height` bug. */
    color: var(--nsy-body);
    background: var(--nsy-page);
    transition: background-color .2s ease;
}

@media (prefers-reduced-motion: reduce) {
    body {
        transition: none;
    }
}

/*
 * Sticky footer: the *content* wrapper absorbs the leftover height so the
 * footer stays pinned to the bottom. It must not be <header> — on a short
 * page (e.g. the HMVC landing) the header would soak up the free space and
 * shove the first section down, leaving a blank band under the <hr>.
 */
.wrap,
.nsy-page,
.nsy-docs {
    flex: 1 0 auto;
    /* Prevent Chrome, Opera, and Safari from letting these items shrink to smaller than their content's default minimum size. */
}

footer {
    flex-shrink: 0;
    /* Prevent Chrome, Opera, and Safari from letting these items shrink to smaller than their content's default minimum size. */
    text-align: center;
}

/* Brand signature: the light-blue "crossing line" from the logo */
hr {
    border: none;
    height: 2px;
    background: var(--nsy-gradient);
    opacity: .9;
}

/* ==========================================================================
  Browser Upgrade Prompt
  ========================================================================== */

.browserupgrade {
    margin: 0.2em 0;
    background: #ccc;
    color: #000;
    padding: 0.2em 0;
}

/* ==========================================================================
  Author's custom styles
  ========================================================================== */

h1,
h2,
h3,
h4,
h5 {
    color: var(--nsy-primary-deep);
}

a {
    color: var(--nsy-primary);
}

a:hover {
    color: var(--nsy-accent-dark);
}

code {
    color: var(--nsy-primary-deep);
    background: var(--nsy-accent-softer);
    border: 1px solid var(--nsy-line);
    border-radius: 6px;
}

.header a:link {
    text-decoration: none;
    color: var(--nsy-primary);
}

/* Site header: NSY logo on the left, welcome copy on the right, theme toggle
   pinned to the top-right corner. */
.header {
    position: relative;
}

.nsy-theme-toggle {
    position: absolute;
    top: 18px;
    right: clamp(16px, 3vw, 44px);
    z-index: 5;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--nsy-line);
    border-radius: 12px;
    background: var(--nsy-surface);
    color: var(--nsy-primary-deep);
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, transform .15s;
}

.nsy-theme-toggle:hover {
    border-color: var(--nsy-accent);
    color: var(--nsy-primary);
    transform: translateY(-1px);
}

.nsy-theme-toggle:focus-visible {
    outline: 2px solid var(--nsy-accent);
    outline-offset: 2px;
}

.nsy-theme-ico {
    display: block;
}

/* Show the moon while light (click → dark), the sun while dark. */
.nsy-theme-ico.sun {
    display: none;
}

[data-theme="dark"] .nsy-theme-ico.sun {
    display: block;
}

[data-theme="dark"] .nsy-theme-ico.moon {
    display: none;
}

.header-inner {
    width: 100%;
    display: flex;
    align-items: center;
    gap: clamp(16px, 3vw, 44px);
    padding: 22px clamp(16px, 3vw, 44px) 14px;
}

.header-logo {
    flex: 0 0 auto;
    display: block;
}

.header-logo img {
    display: block;
    width: clamp(84px, 11vw, 132px);
    height: auto;
}

.header-copy {
    min-width: 0;
}

.header-copy h1 {
    margin: 0 0 6px;
    font-size: clamp(21px, 2.6vw, 34px);
    line-height: 1.15;
}

.header-copy h3 {
    margin: 0;
    font-size: clamp(12px, 1.2vw, 15px);
    font-weight: 400;
}

.header-copy code {
    font-size: .95em;
}

@media (max-width: 560px) {
    .header-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 14px;
    }
}

.wrap h3 {
    color: var(--nsy-primary-deep);
}

.wrap h1 {
    color: var(--nsy-primary-deep);
}

.wrap a:link {
    text-decoration: none;
    color: var(--nsy-primary);
}

.footer a:link,
.footer h1 {
    text-decoration: none;
    color: var(--nsy-primary);
}

.footer .fcontent {
    padding: 2em;
}

/* Footer meta line. The dot separators live in CSS rather than as &nbsp;|&nbsp;
   in the markup, so the row wraps cleanly on narrow screens and the dots stay
   decorative (never announced by a screen reader). */
.footer-date {
    margin: 0 0 6px;
    font-size: 12.5px;
    color: var(--nsy-muted);
}

.footer-links {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 2px 0;
    font-size: 12.5px;
    color: var(--nsy-muted);
}

.footer-links>*+*::before {
    content: '\00b7';
    margin: 0 8px;
    color: var(--nsy-accent);
}

.footer-links a:hover {
    color: var(--nsy-accent-dark);
}

.footer-links span {
    color: var(--nsy-primary-deep);
}

/* ==========================================================================
  Documentation index — System/Apps/General/Views/Index_Welcome.php
  ========================================================================== */

/* Full-width page shell with fluid gutters + breathing room above the footer.
   No margin-top here on purpose — see the desktop-only rule below. */
.nsy-page {
    width: 100%;
    padding: 0 clamp(16px, 3vw, 44px) clamp(24px, 4vw, 48px);
}

/* Desktop only. On wide screens the shell sits far from the header and needs a
   little air above it; on phones the gutter is already tight, so the extra
   space only pushed the content down. Paired with the 860px breakpoint the
   documentation viewer uses for its grid. */
@media (min-width: 861px) {
    .nsy-page {
        margin-top: 14px;
    }
}

/* Hero: search-first — badge above, Search label + large centered input. */
.nsy-hero {
    width: 100%;
    padding: 32px 0 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.nsy-badge {
    display: inline-block;
    background: var(--nsy-gradient);
    color: var(--nsy-on-primary);
    padding: 5px 14px;
    border-radius: 999px;
    font-size: 14px;
    letter-spacing: .08em;
    margin-bottom: 12px;
}

.nsy-hero-caption {
    font-size: 15px;
    font-weight: 600;
    color: var(--nsy-body);
    margin: 0 10px 0 0;
    white-space: nowrap;
    flex: 0 0 auto;
}

.nsy-hero-searchwrap {
    width: 100%;
    max-width: 560px;
    display: flex;
    align-items: center;
}

.nsy-hero-search {
    flex: 1;
    min-width: 0;
    padding: 14px 18px;
    border: 2px solid var(--nsy-line);
    border-radius: 12px;
    font-size: 16px;
    outline: none;
    color: var(--nsy-body);
    background: var(--nsy-surface);
    transition: border-color .15s, box-shadow .15s;
}

.nsy-hero-search::placeholder {
    color: var(--nsy-muted);
}

.nsy-hero-search:focus {
    border-color: var(--nsy-accent);
    box-shadow: 0 0 0 3px var(--nsy-focus-ring);
}

.nsy-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    flex-wrap: wrap;
    margin: 0;
}

.nsy-btn {
    padding: 10px 18px;
    border-radius: 10px;
    text-decoration: none;
    font-weight: 600;
    border: 1px solid var(--nsy-line);
    display: inline-block;
    color: var(--nsy-primary);
    transition: background .15s, border-color .15s, color .15s;
}

.nsy-btn.primary {
    background: var(--nsy-primary);
    color: var(--nsy-on-primary);
    border-color: var(--nsy-primary);
}

.nsy-btn.primary:hover {
    background: var(--nsy-primary-dark);
    border-color: var(--nsy-primary-dark);
    color: var(--nsy-on-primary);
}

.nsy-btn.ghost {
    background: var(--nsy-surface);
    color: var(--nsy-primary);
}

.nsy-btn.ghost:hover {
    border-color: var(--nsy-accent);
    color: var(--nsy-accent-dark);
}

.nsy-dochead {
    width: 100%;
    margin: 12px 0 0;
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
}

.nsy-dochead h2 {
    font-size: 18px;
    margin: 0;
    color: var(--nsy-primary-deep);
}

.nsy-dochead .nsy-hint {
    font-size: 12px;
    color: var(--nsy-muted);
    font-weight: 400;
    margin-left: 6px;
}

.nsy-cat {
    width: 100%;
    margin: 0;
    padding: 20px 0 0;
    position: relative;
    --cat: var(--nsy-primary);
    --cat-soft: var(--nsy-accent-soft);
}

/* Per-category accents, all drawn from the logo-blue family. */
.nsy-cat[data-cat="getting-started"] {
    --cat: #1D7BBA;
    --cat-soft: #E7F1F9;
}

.nsy-cat[data-cat="core"] {
    --cat: #3D9BE8;
    --cat-soft: #EAF5FE;
}

.nsy-cat[data-cat="reference"] {
    --cat: #6E8CA6;
    --cat-soft: #EEF3F7;
}

/* A thick gradient rule between groups so the categories never blur together. */
.nsy-cat+.nsy-cat {
    margin-top: 14px;
    padding-top: 34px;
}

.nsy-cat+.nsy-cat::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    border-radius: 999px;
    background: var(--nsy-gradient);
    opacity: .9;
}

.nsy-cat-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
}

.nsy-cat-head h3 {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 12px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--cat);
    margin: 0;
}

/* Thicker accent bar before the label: the quickest cue for which group you are in. */
.nsy-cat-head h3::before {
    content: "";
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background: var(--cat);
    flex: 0 0 auto;
}

.nsy-cat-count {
    margin-left: auto;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    color: var(--cat);
    background: var(--cat-soft);
    padding: 5px 10px;
    border-radius: 999px;
}

.nsy-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    gap: 16px;
}

.nsy-card {
    border: 1px solid var(--nsy-line);
    border-radius: 14px;
    padding: 16px;
    background: var(--nsy-surface);
    transition: box-shadow .15s, transform .15s, border-color .15s;
    display: flex;
    flex-direction: column;
}

.nsy-card:hover {
    box-shadow: var(--nsy-shadow);
    transform: translateY(-2px);
    border-color: var(--nsy-accent);
}

.nsy-card h4 {
    margin: 0 0 8px;
    font-size: 15px;
}

.nsy-card h4 a {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--nsy-primary-deep);
    text-decoration: none;
}

.nsy-card h4 a:hover {
    color: var(--nsy-primary);
}

.nsy-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--nsy-accent-soft);
    border: 1px solid var(--nsy-line);
    color: var(--nsy-primary);
    flex: 0 0 auto;
    transition: background .15s, color .15s, border-color .15s;
}

.nsy-ico svg {
    display: block;
}

.nsy-card:hover .nsy-ico {
    background: var(--nsy-primary);
    border-color: var(--nsy-primary);
    color: var(--nsy-on-primary);
}

.nsy-card code {
    font-size: 11.5px;
    color: var(--nsy-primary-deep);
    background: var(--nsy-accent-softer);
    border: 1px solid var(--nsy-line);
    padding: 2px 7px;
    border-radius: 6px;
    align-self: flex-start;
}

.nsy-card p {
    margin: 10px 0 0;
    font-size: 12.5px;
    color: var(--nsy-body);
    line-height: 1.5;
    flex: 1;
}

.nsy-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 12px;
    font-size: 12px;
    color: var(--nsy-muted);
}

.nsy-card-foot .more {
    color: var(--nsy-primary);
    text-decoration: none;
    font-weight: 600;
}

.nsy-card-foot .more:hover {
    color: var(--nsy-accent-dark);
}

.nsy-card-foot .ext {
    color: var(--nsy-muted);
    text-decoration: none;
    font-size: 13px;
}

.nsy-card-foot .ext:hover {
    color: var(--nsy-primary);
}

.nsy-empty {
    width: 100%;
    margin: 24px 0;
    padding: 32px;
    text-align: center;
    color: var(--nsy-muted);
    border: 1px dashed var(--nsy-line);
    border-radius: 14px;
    display: none;
}

/* Callout prompt anchored to the Releases button. */
.nsy-callout {
    position: fixed;
    z-index: 9999;
    display: inline-block;
    left: 0;
    top: 0;
    transform: translateY(6px) scale(.96);
    opacity: 0;
    background: var(--nsy-primary);
    color: var(--nsy-on-primary);
    padding: 8px 15px;
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: var(--nsy-shadow-strong);
    pointer-events: none;
    transition: opacity .22s, transform .22s;
}

.nsy-callout.show {
    transform: translateY(0) scale(1);
    opacity: 1;
}

.nsy-callout::after {
    content: '';
    position: absolute;
    left: var(--arrow-x, 50%);
    transform: translateX(-50%);
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
}

.nsy-callout[data-placement="top"]::after {
    bottom: -6px;
    border-top: 6px solid var(--nsy-primary);
}

.nsy-callout[data-placement="bottom"]::after {
    top: -6px;
    border-top: none;
    border-bottom: 6px solid var(--nsy-primary);
}

@media (max-width: 480px) {
    .nsy-callout {
        padding: 7px 12px;
        font-size: 12px;
        border-radius: 9px;
    }
}

/* ==========================================================================
  Documentation viewer — System/Apps/General/Views/Index_Docs.php
  ========================================================================== */

/* The viewer reuses the .nsy-page shell for its gutters, so the sidebar edge
   lines up with the documentation index and the HMVC page. The grid itself is
   capped so the reading column keeps a comfortable measure (~900px) instead of
   stretching edge-to-edge on wide screens. */
.nsy-docs {
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 26px;
    align-items: start;
}

.nsy-docs-side {
    position: sticky;
    top: 16px;
    align-self: start;
    max-height: calc(100vh - 32px);
    overflow: auto;
    border: 1px solid var(--nsy-line);
    border-radius: 14px;
    padding: 14px;
    background: var(--nsy-surface);
}

.nsy-docs-home {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--nsy-primary);
    text-decoration: none;
    margin-bottom: 12px;
}

.nsy-docs-home:hover {
    color: var(--nsy-accent-dark);
}

.nsy-docs-group {
    margin-bottom: 14px;
}

.nsy-docs-group-title {
    display: block;
    font-size: 10.5px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--nsy-muted);
    font-weight: 700;
    margin-bottom: 6px;
}

.nsy-docs-link {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 9px;
    border-radius: 8px;
    font-size: 13px;
    color: var(--nsy-body);
    text-decoration: none;
    transition: background .15s, color .15s;
}

.nsy-docs-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: inherit;
    opacity: .6;
    flex: 0 0 auto;
}

.nsy-docs-ico svg {
    display: block;
}

.nsy-docs-link:hover .nsy-docs-ico,
.nsy-docs-link.active .nsy-docs-ico {
    opacity: 1;
}

.nsy-docs-link:hover {
    background: var(--nsy-accent-soft);
    color: var(--nsy-primary-deep);
}

.nsy-docs-link.active {
    background: var(--nsy-primary);
    color: var(--nsy-on-primary);
}

.nsy-docs-toc {
    border-top: 1px solid var(--nsy-line);
    padding-top: 12px;
    margin-top: 4px;
}

.nsy-docs-toc-link {
    display: block;
    padding: 3px 9px;
    font-size: 12px;
    color: var(--nsy-muted);
    text-decoration: none;
    border-left: 3px solid transparent;
    /* One entry, one line — always.
       A long heading ellipsizes rather than wrapping, so the list keeps an even
       rhythm and the reader can scan it quickly. The sidebar is a fixed 250px
       column, so "nowrap" on its own would push the text out of the panel; the
       full heading is kept in the link's title attribute for hover. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nsy-docs-toc-link:hover {
    color: var(--nsy-primary);
    border-left-color: var(--nsy-accent);
}

/* "On this page" scroll spy. Placed after :hover on purpose — same specificity,
   so the marker survives the pointer passing over it. Deliberately lighter than
   .nsy-docs-link.active (solid blue) so the two never read as the same thing. */
.nsy-docs-toc-link.active {
    background: var(--nsy-accent-soft);
    color: var(--nsy-primary-deep);
    border-left-color: var(--nsy-primary);
    font-weight: 600;
}

/* "On this page" list.
 *
 * Only the numbered sections appear here: System\Libraries\Markdown marks every
 * level-2 heading with a 'num' and System\Libraries\Docs keeps just those, so
 * group titles (h1) and subsections (h3+) never reach the template. One flat
 * list means no level classes and no indent scale to maintain.
 */
/* Number prefix. Left-aligned with a min-width so the entry text forms a
   column: "1." and "10." both leave the label starting at the same offset. */
.nsy-toc-no {
    display: inline-block;
    min-width: 1.6em;
    color: var(--nsy-muted);
    font-variant-numeric: tabular-nums;
}

.nsy-docs-toc-link.active .nsy-toc-no {
    color: var(--nsy-primary);
}

.nsy-docs-main {
    min-width: 0;
}

/* Page head: same .nsy-badge treatment as the index and the HMVC page, kept
   slim so it does not eat the reader's vertical space. */
.nsy-docs-head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
    margin-bottom: 20px;
    padding-bottom: 14px;
    border-bottom: 2px solid var(--nsy-line);
}

.nsy-docs-head .nsy-badge {
    margin-bottom: 0;
}

.nsy-docs-head .nsy-docs-crumbs {
    margin-bottom: 0;
}

/* Metadata line mirrors the documentation card foot: api pill, category, size. */
.nsy-docs-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--nsy-muted);
}

.nsy-docs-meta code {
    font-size: 11.5px;
    color: var(--nsy-primary-deep);
    background: var(--nsy-accent-softer);
    border: 1px solid var(--nsy-line);
    padding: 2px 7px;
    border-radius: 6px;
}

.nsy-docs-meta a.ext {
    color: var(--nsy-muted);
    text-decoration: none;
    font-size: 13px;
}

.nsy-docs-meta a.ext:hover {
    color: var(--nsy-primary);
}

.nsy-docs-crumbs {
    font-size: 12px;
    color: var(--nsy-muted);
    margin-bottom: 10px;
}

.nsy-docs-crumbs a {
    color: var(--nsy-primary);
    text-decoration: none;
}

.nsy-docs-crumbs a:hover {
    color: var(--nsy-accent-dark);
}

.nsy-docs-pager {
    display: flex;
    gap: 12px;
    justify-content: space-between;
    margin-top: 32px;
    border-top: 1px solid var(--nsy-line);
    padding-top: 16px;
}

.nsy-pager {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-decoration: none;
    border: 1px solid var(--nsy-line);
    border-radius: 12px;
    padding: 10px 14px;
    min-width: 150px;
    color: var(--nsy-primary-deep);
    transition: box-shadow .15s, border-color .15s;
}

.nsy-pager:hover {
    box-shadow: var(--nsy-shadow);
    border-color: var(--nsy-accent);
}

.nsy-pager span {
    font-size: 11px;
    color: var(--nsy-muted);
}

.nsy-pager strong {
    font-size: 13px;
}

.nsy-pager.next {
    text-align: right;
    margin-left: auto;
}

.nsy-docs-missing {
    text-align: center;
    border: 1px dashed var(--nsy-line);
    border-radius: 16px;
    padding: 48px 20px;
    color: var(--nsy-body);
}

.nsy-docs-missing h2 {
    color: var(--nsy-primary-deep);
    margin: 0 0 6px;
}

.nsy-docs-missing .nsy-btn {
    margin-top: 14px;
}

/* Back to top.
 *
 * A plain "#top" anchor, so jumping up needs no JS at all. It is visible by
 * default and the .js gate hides it until the reader has scrolled into the
 * article — that way the control is still there (and usable) when JS is off,
 * and it never flashes on screen while the script is loading. */
.nsy-top {
    position: fixed;
    right: clamp(14px, 2.6vw, 40px);
    bottom: clamp(14px, 2.6vw, 40px);
    z-index: 900;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--nsy-line);
    border-radius: 50%;
    background: var(--nsy-surface);
    color: var(--nsy-primary);
    text-decoration: none;
    box-shadow: var(--nsy-shadow);
    transition: background .15s, color .15s, border-color .15s;
}

.nsy-top svg {
    display: block;
}

.nsy-top:hover {
    background: var(--nsy-primary);
    border-color: var(--nsy-primary);
    color: var(--nsy-on-primary);
}

.nsy-top:focus-visible {
    outline: 2px solid var(--nsy-accent);
    outline-offset: 2px;
}

/* Show/hide is a straight visibility flip — no fade.
 *
 * Fading would mean opacity only reaches 1 once the transition clock has run,
 * which makes the button's presence depend on the animation machinery rather
 * than on the class. A control whose whole job is "be there when you need it"
 * is the wrong place for that trade: an instant appearance is worth more than
 * a fade that can be a no-op. */
.js .nsy-top {
    visibility: hidden;
}

.js .nsy-top.is-visible {
    visibility: visible;
}

/* Rendered Markdown (output of System\Libraries\Markdown) */
.md {
    font-size: 15px;
    line-height: 1.68;
    color: var(--nsy-body);
    overflow-wrap: anywhere;
}

.md h1,
.md h2,
.md h3,
.md h4,
.md h5,
.md h6 {
    color: var(--nsy-primary-deep);
    line-height: 1.3;
    margin: 1.6em 0 .6em;
    scroll-margin-top: 16px;
}

.md h1 {
    font-size: 26px;
    border-bottom: 3px solid var(--nsy-accent);
    padding-bottom: .3em;
    margin-top: .2em;
}

.md h2 {
    font-size: 21px;
    border-bottom: 2px solid var(--nsy-line);
    padding-bottom: .25em;
}

.md h3 {
    font-size: 17px;
}

.md h4 {
    font-size: 15px;
}

.md p {
    margin: .7em 0;
}

.md a {
    color: var(--nsy-primary);
    text-decoration: none;
}

.md a:hover {
    text-decoration: underline;
    color: var(--nsy-accent-dark);
}

.md strong {
    color: var(--nsy-primary-deep);
}

.md ul,
.md ol {
    margin: .6em 0;
    padding-left: 1.6em;
}

.md li {
    margin: .28em 0;
}

.md li>ul,
.md li>ol {
    margin: .2em 0;
}

.md blockquote {
    margin: 1em 0;
    padding: .2em 1em;
    border-left: 5px solid var(--nsy-accent);
    background: var(--nsy-accent-softer);
    border-radius: 0 10px 10px 0;
    color: var(--nsy-body);
}

.md hr {
    border: none;
    height: 2px;
    background: var(--nsy-gradient);
    margin: 1.6em 0;
}

.md code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .9em;
}

.md :not(pre)>code {
    background: var(--nsy-accent-soft);
    color: var(--nsy-primary-deep);
    padding: 1px 6px;
    border-radius: 6px;
    border: 1px solid var(--nsy-line);
}

.md pre.md-pre {
    background: var(--nsy-code-bg);
    color: var(--nsy-code-fg);
    padding: 14px 16px;
    border-radius: 12px;
    overflow: auto;
    font-size: 12.5px;
    line-height: 1.55;
    margin: 1em 0;
}

.md pre.md-pre code {
    background: none;
    border: none;
    color: inherit;
    font-size: 12.5px;
}

.md-table-wrap {
    overflow: auto;
    margin: 1em 0;
    border: 1px solid var(--nsy-line);
    border-radius: 12px;
}

.md table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
    margin: 0;
}

.md th,
.md td {
    border-bottom: 1px solid var(--nsy-line);
    border-right: 1px solid var(--nsy-line);
    padding: 8px 12px;
    text-align: left;
    vertical-align: top;
}

.md th {
    background: var(--nsy-accent-softer);
    color: var(--nsy-primary-deep);
    font-weight: 700;
}

.md tr:last-child td {
    border-bottom: none;
}

.md img {
    max-width: 100%;
    border-radius: 8px;
}

.md mark {
    background: var(--nsy-mark);
    color: var(--nsy-mark-fg);
    padding: 0 3px;
    border-radius: 3px;
}

.md del {
    color: var(--nsy-muted);
}

@media (max-width: 860px) {
    .nsy-docs {
        grid-template-columns: 1fr;
        /* Mobile only: the "Docs menu" button becomes the first grid row here, so
           without this the block sits flush against the header above it. Desktop
           is untouched (the sidebar is the left column there, not a row). */
        margin-top: 14px;

        /* Rows stack, and the grid's own gap would then sit between the button
           and the drawer — a blank band with two visible edges on it. Gap is
           zeroed and each block owns its spacing instead: the button and the
           open drawer meet flush, while the article keeps its air. */
        gap: 0;
    }

    /* The button itself carries no bottom margin, so the drawer can attach
       directly underneath it. Closed, that space is taken by the article rule
       below, so the button is never left hugging the content. */
    .nsy-docs-main {
        margin-top: 16px;
    }

    .nsy-docs-side {
        position: static;
        max-height: none;
    }
}

/* Small screens: the doc sidebar becomes a slide-in drawer, opened by the
   "Docs menu" button. Above the breakpoint the button is hidden and the
   sidebar keeps its sticky desktop position — the .open class never matters. */
.nsy-docs-menu-btn {
    display: none;
    align-items: center;
    gap: 8px;
    align-self: start;
    padding: 9px 14px;
    border: 1px solid var(--nsy-line);
    border-radius: 10px;
    background: var(--nsy-surface);
    color: var(--nsy-primary);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
}

@media (max-width: 860px) {
    .nsy-docs-menu-btn {
        display: inline-flex;
    }

    .nsy-docs-side {
        display: none;
    }

    .nsy-docs-side.open {
        display: block;
        position: relative;
        max-height: none;
    }
}

/* Keep the prev/next pager from forcing a horizontal scroll on tiny screens. */
@media (max-width: 560px) {
    .nsy-docs-pager {
        flex-direction: column;
    }

    .nsy-pager {
        min-width: 0;
    }

    .nsy-pager.next {
        text-align: left;
        margin-left: 0;
    }
}

/* Document page head on small screens — Index_Docs.php. Mobile only; the
   desktop rules in the .nsy-docs-head block above stay untouched.

   margin-top: the header sits directly below the site header there, so it needs
   its own breathing room.

   The badge is the widest fixed string on the page ("Documentation • v7.0.0
   Gamelan"): at its desktop size it either overflows the gutter or breaks in an
   awkward place, so it shrinks, tightens its tracking and is allowed to wrap
   between words — never inside one, since the pill background would show the
   seam. The crumbs and metadata row keep wrapping but get roomier spacing. */
@media (max-width: 560px) {
    .nsy-docs-head {
        margin-top: 14px;
        gap: 8px;
        margin-bottom: 16px;
        padding-bottom: 12px;
    }

    .nsy-docs-head .nsy-badge {
        /* Full-bleed pill on phones: .nsy-badge is inline-block (content width)
           and .nsy-docs-head is a column flex with align-items:flex-start, so
           without this it stays a short pill on the left at every width. */
        width: 100%;
        text-align: center;
        max-width: 100%;
        padding: 5px 12px;
        font-size: 12px;
        letter-spacing: .04em;
        line-height: 1.5;
        overflow-wrap: break-word;
    }

    .nsy-docs-crumbs {
        font-size: 11.5px;
        line-height: 1.6;
    }

    .nsy-docs-meta {
        gap: 6px 10px;
    }
}

/* Documentation index on small screens — Index_Welcome.php (shared with the
   HMVC landing, which reuses .nsy-actions). The "Search" label is dropped —
   the input keeps its placeholder plus an aria-label — and the action buttons
   stack full-width so none of them wraps or overflows. */
@media (max-width: 560px) {
    .nsy-hero-caption {
        display: none;
    }

    .nsy-dochead {
        flex-direction: column;
        align-items: stretch;
    }

    .nsy-actions {
        width: 100%;
        flex-direction: column;
        justify-content: stretch;
    }

    .nsy-actions .nsy-btn {
        text-align: center;
    }
}

/* ==========================================================================
  HMVC landing — System/Apps/Modules/HMVC/Views/Index_Hello.php
  ========================================================================== */

/* The HMVC page reuses the documentation-index theme verbatim: same full-width
   .nsy-page shell, same .nsy-hero badge, same .nsy-btn actions, same
   .nsy-card grid. Only these two pieces are page-specific. */
.nsy-hero-title {
    font-size: clamp(22px, 2.8vw, 30px);
    font-weight: 800;
    margin: 0 0 6px;
    color: var(--nsy-primary-deep);
}

.nsy-hero-lead {
    color: var(--nsy-body);
    margin: 0;
    max-width: 760px;
    font-size: 14px;
    line-height: 1.6;
}

/* Page-level CTAs sit in the hero on pages without a docs index below them. */
.nsy-hero-actions {
    justify-content: center;
    margin-top: 18px;
}

/* Explainer callout below the hero. */
.nsy-note {
    width: 100%;
    margin: 18px 0 0;
    padding: 14px 16px;
    background: var(--nsy-accent-softer);
    border: 1px solid var(--nsy-line);
    border-left: 4px solid var(--nsy-accent);
    border-radius: 12px;
    color: var(--nsy-body);
    font-size: 13px;
    line-height: 1.6;
}

.nsy-note strong {
    color: var(--nsy-primary-deep);
}

/* Long file paths / signatures in inline code must wrap, or they widen the page. */
.nsy-hero code,
.nsy-note code {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Cards that carry no category heading sit a little tighter to the top. */
.nsy-cat>.nsy-grid {
    padding-top: 0;
}

/* ==========================================================================
  Pagination (NSY_Paginator / paginate_links())
  ========================================================================== */

.nsy-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 22px 0;
}

.nsy-pagination-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    height: 38px;
    padding: 0 10px;
    border: 1px solid var(--nsy-line);
    border-radius: 10px;
    background: var(--nsy-surface);
    color: var(--nsy-primary);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    transition: background .15s, border-color .15s, color .15s;
}

a.nsy-pagination-link:hover {
    border-color: var(--nsy-accent);
    color: var(--nsy-accent-dark);
}

.nsy-pagination-link.is-active {
    background: var(--nsy-primary);
    border-color: var(--nsy-primary);
    color: var(--nsy-on-primary);
}

.nsy-pagination-link.is-disabled {
    opacity: .45;
    cursor: default;
}

.nsy-pagination-ellipsis {
    padding: 0 4px;
    color: var(--nsy-muted);
}