/*
 * Yggdrasil sitewide theme — self-hosted fonts + app-shell chrome.
 *
 * SCOPE GUARD: global chrome (navbar/footer/typography) lives in the Tailwind
 * layer (tailwind.css / tailwind.src.css); component behaviour styling lives in
 * ygg-ui.css. This file keeps only:
 *   1. @font-face for the self-hosted IBM Plex families (GDPR: no CDN fonts).
 *   2. The fixed footer + 64px icon-rail app-shell layout.
 *   3. The desktop-only gate shown at phone widths.
 * It MUST NOT restyle annotation viewers — viewer pages inherit this file.
 *
 * Bootstrap is gone as of the 2.0 rebuild; the chromatic overrides and the
 * Bootstrap dark remap that used to live here went with it.
 *
 * Tokens live in tokens.css (loaded first).
 */

/* ---- Self-hosted webfonts (IBM Plex Sans + Mono) ----------------------- */
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal; font-weight: 400; font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal; font-weight: 500; font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal; font-weight: 600; font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal; font-weight: 700; font-display: swap;
    src: url('../fonts/ibm-plex-sans-latin-700-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal; font-weight: 400; font-display: swap;
    src: url('../fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal; font-weight: 500; font-display: swap;
    src: url('../fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal; font-weight: 600; font-display: swap;
    src: url('../fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2');
}

/* ==========================================================================
 * Yggdrasil 2.0 chrome — sticky footer, full-width nav, branding assets.
 * Plain CSS (loaded after tailwind.css, so these override compiled utilities).
 * ======================================================================== */

/* Fixed footer: pinned to the viewport bottom at all times; body reserves room
 * so content is never hidden behind it. (Landing blanks the footer + is its own
 * 100vh overflow-hidden viewport, so it's unaffected.) */
:root {
    --ygg-footer-h: 3rem;
    --ygg-maintenance-h: 2rem;
}
body { min-height: 100vh; padding-bottom: var(--ygg-footer-h); }
.maintenance-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2100;
    height: var(--ygg-maintenance-h);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 1rem;
    overflow: hidden;
    border-bottom: 1px solid #dfbd35;
    background: #f5dc69;
    color: #493900;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1;
}
.maintenance-banner span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
body.has-maintenance-banner { padding-top: var(--ygg-maintenance-h); }
body.has-maintenance-banner .ygg-nav,
body.has-maintenance-banner .ygg-topbar { top: var(--ygg-maintenance-h); }
body.has-maintenance-banner .ygg-toast-container {
    top: calc(var(--ygg-maintenance-h) + 1rem);
}
body.has-maintenance-banner main.landing {
    min-height: calc(100vh - var(--ygg-maintenance-h));
}
:root[data-theme="dark"] .maintenance-banner {
    border-bottom-color: #b79520;
    background: #d8bb43;
    color: #211a00;
}
.ygg-footer {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
}

/* Full-width navbar: brand flush-left, profile flush-right (drop max-width). */
.ygg-nav-inner { max-width: none; }
.ygg-topbar { z-index: 100; }

/* Tree logo beside the wordmark in the navbar. */
.ygg-brand-logo { height: 1.6rem; width: auto; display: block; }

/* Footer: AImageLab credit logo. */
.footer-aimagelab { height: 1.45rem; width: auto; display: inline-block; }

/* ==========================================================================
 * App shell — 64px fixed icon rail (working pages opt in via body.has-rail).
 * Additive layout: the rail is position:fixed and the body reserves 64px on
 * the left, so the existing document flow (main + fixed footer) is untouched
 * except for the horizontal offset. Landing/auth pages don't set the class.
 * ======================================================================== */
:root { --ygg-rail-w: 64px; }
.ygg-rail {
    position: fixed;
    top: 0;
    left: 0;
    width: var(--ygg-rail-w);
    height: 100vh;
    z-index: 45;
}
body.has-maintenance-banner .ygg-rail {
    top: var(--ygg-maintenance-h);
    height: calc(100vh - var(--ygg-maintenance-h));
}
body.has-rail { padding-left: var(--ygg-rail-w); }
body.has-rail .ygg-footer { left: var(--ygg-rail-w); }
@media (max-width: 640px) {
    /* Collapse the rail off-canvas on very small screens; content reclaims width. */
    body.has-rail { padding-left: 0; }
    body.has-rail .ygg-rail { transform: translateX(-100%); transition: transform .2s; }
    body.has-rail.rail-open .ygg-rail { transform: none; }
    body.has-rail .ygg-footer { left: 0; }
}

/* ==========================================================================
 * Desktop-only gate — the honest counterpart to the rule above.
 *
 * Below phone width the rail is translated off-canvas and nothing reopens it,
 * and the viewers were never laid out for a 390px column. Rather than serve a
 * silently broken page, base.html carries an interstitial that is invisible at
 * desktop widths and paints over everything here. No JS and no User-Agent
 * sniffing: the media query IS the detection. Colours are all --ygg-* tokens,
 * so it follows the data-theme stamp with no dark-mode rules of its own.
 *
 * The landscape clause catches a rotated phone (~850px wide, so a bare
 * max-width would let it through); max-height keeps laptops out.
 * ======================================================================== */
.ygg-desktop-gate { display: none; }

@media (max-width: 640px), (orientation: landscape) and (max-height: 480px) {
    html, body { overflow: hidden; }
    .ygg-desktop-gate {
        display: flex;
        position: fixed;
        inset: 0;
        /* Above the maintenance banner (2100), toasts (2000) and modals (1050). */
        z-index: 3000;
        align-items: center;
        justify-content: center;
        padding: 1.5rem;
        background: var(--ygg-surface-alt);
    }
    .ygg-desktop-gate__card {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.75rem;
        max-width: 22rem;
        padding: 2rem 1.5rem 1.75rem;
        border: 1px solid var(--ygg-border);
        border-radius: var(--ygg-radius-lg);
        background: var(--ygg-surface);
        box-shadow: var(--ygg-shadow-card-light);
        text-align: center;
    }
    .ygg-desktop-gate__logo {
        width: 4.5rem;
        height: auto;
        animation: ygg-gate-float 3.2s ease-in-out infinite;
    }
    .ygg-desktop-gate__title {
        margin-top: 0.5rem;
        font-size: 1.125rem;
        line-height: 1.4;
    }
    .ygg-desktop-gate__text {
        margin: 0;
        color: var(--ygg-text-muted);
        font-size: 0.875rem;
        line-height: 1.55;
    }
}

@keyframes ygg-gate-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) {
    .ygg-desktop-gate__logo { animation: none; }
}
