/*
 * Terminal Theme for barnholt.net — the whole thing, one file.
 * (Was split into terminal-minimal + terminal-effects; no page ever loaded
 *  one without the other, and effects overrode the base body background.)
 */

/* Courier Prime, self-hosted so no visitor request leaves this server.
   SIL Open Font License 1.1, see /fonts/OFL.txt */
@font-face {
    font-family: 'Courier Prime';
    font-style: normal;
    font-weight: 400;
    src: url('/fonts/courier-prime-latin-400-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'Courier Prime';
    font-style: normal;
    font-weight: 700;
    src: url('/fonts/courier-prime-latin-700-normal.woff2') format('woff2');
}

/* ============================================
   BASE STYLES
   ============================================ */
html {
    background: #000000;
    height: 100%;
}

body {
    margin: 0;
    padding: 0;
    /* Faint green wash over the black html backdrop */
    background: radial-gradient(
        ellipse at center,
        rgba(0, 0, 0, 0) 50%,
        rgba(61, 150, 51, 0.2) 250%
    ),
    rgba(61, 150, 51, 0.15);
    color: #6dfd60;
    font-family: 'Courier Prime', 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.6;
    min-height: 100vh;
}

/* CRT phosphor glow */
body, h1, h2, p, li, a {
    text-shadow: 0 0 5px #6dfd60;
}

/* Vignette: dark edges fade. Sits under the lightbox overlay (z-index 9999). */
body:before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: radial-gradient(
        ellipse at center,
        transparent 0%,
        transparent 70%,
        rgba(0, 0, 0, 0.95) 100%
    );
    pointer-events: none;
    z-index: 9998;
}

/* ============================================
   TYPOGRAPHY
   ============================================ */
h1, h2 {
    color: #6dfd60;
    font-weight: normal;
}

h1 { font-size: 2.5em; }
h2 { font-size: 1.8em; }

/* ============================================
   LINKS
   ============================================ */
a {
    color: #6dfd60;
    text-decoration: none;
    border-bottom: 1px dotted #6dfd60;
    padding: 2px 4px;
}

a:hover {
    background-color: #6dfd60;
    color: #000000;
    text-decoration: none;
    text-shadow: none; /* inverted pill: glow would smear the black text */
    box-shadow: 0 0 10px #6dfd60;
}

/* ============================================
   LAYOUT - Matching your existing structure
   ============================================ */
.contentbox {
    background-color: rgba(0, 0, 0, 0.6);
    width: 800px;
    margin: 20px auto;
    padding: 0;
    min-height: calc(100vh - 40px);
    display: flex;
}

/* Sidebar */
#sidebar {
    width: 241px;
    display: flex;
    flex-direction: column;
}

/* Widgets/Navigation */
#widgets {
    padding-top: 60px;
}

#widgets-main-title {
    padding: 20px 15px;
}

#widgets ul {
    list-style: none;
    margin: 0;
    padding: 0 0 20px 20px;
}

#widgets li {
    margin-bottom: 8px;
    position: relative;
}

#widgets li:before {
    content: "> ";
    position: absolute;
    left: -15px;
}

#widgets a {
    border: none;
    display: inline-block;
}

#widgets a:hover {
    background: #6dfd60;
    color: #000000;
    text-decoration: none;
}

/* Main content */
#page {
    flex: 1;
    padding: 20px;
    display: flex;
    flex-direction: column;
}

.pagetitle {
    text-align: right;
    letter-spacing: 3px;
    margin: 0 0 20px 0;
    padding: 10px 0;
    border-bottom: 2px solid rgba(109, 253, 96, 0.3);
    font-size: 1.2em;
    font-weight: normal;
}

/* Product page sections */
.post-title {
    margin: 30px 0 15px 0;
    padding: 0;
    font-size: 1.8em;
    color: #6dfd60;
}

.post-content {
    padding: 0 0 20px 0;
    margin-bottom: 20px;
}

/* Footer */
#footer {
    padding: 20px;
    text-align: center;
    font-size: 0.9em;
    margin-top: auto;
}

#footer p {
    margin: 5px 0;
}

/* ============================================
   CONTENT UTILITIES
   ============================================ */

/* Highlighted terms/definitions */
.term {
    color: #6dfd60;
    font-weight: bold;
}

/* Project/item lists with box styling */
.item-list {
    list-style: none;
    padding-left: 0;
}

.item-list li {
    margin-bottom: 2em;
    padding: 10px 15px;
    border: 1px solid rgba(109, 253, 96, 0.3);
    position: relative;
}

.item-list li:before {
    content: "";
}

.item-list a {
    font-weight: bold;
    display: block;
    margin-bottom: 5px;
    border: none;
}

.item-list .description {
    display: block;
    font-weight: normal;
}

.item-list .os-label {
    font-weight: bold;
    background-color: #2d6b20;
    color: #000;
    /* the pill is a solid cut-out: kill the inherited li phosphor glow */
    text-shadow: none;
    padding: 1px 7px;
    border-radius: 2px;
}

/* Album styling with nested song lists */
.item-list .album-title {
    font-weight: bold;
    font-size: 1.1em;
    margin-bottom: 5px;
}

.item-list .album-description {
    margin-bottom: 10px;
    opacity: 0.8;
}

.item-list .song-list {
    list-style: none;
    padding-left: 0;
    margin: 10px 0 0 0;
    border-top: 1px solid rgba(109, 253, 96, 0.2);
    padding-top: 10px;
}

.item-list .song-list li {
    margin-bottom: 0.5em;
    padding: 0;
    border: none;
    position: relative;
    padding-left: 15px;
}

.item-list .song-list li:before {
    content: "♪ ";
    position: absolute;
    left: 0;
    opacity: 0.6;
}

.item-list .song-list a {
    font-weight: normal;
    display: inline;
    margin: 0;
}

/* Screenshot galleries for product pages */
.screenshot-gallery {
    padding: 20px;
    margin: 20px 0;
    border: 1px solid rgba(109, 253, 96, 0.3);
    text-align: center;
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
}

/* Green-CRT phosphor duotone (luminance→#6dfd60) — shared by screenshots AND app icons.
   The filter itself is inlined in every page as <svg id="phosphor">. Two earlier
   forms failed: an SVG data URI (Safari does not resolve filter refs from one, so
   every thumbnail rendered in raw colour) and a plain hue-rotate chain (WebKit
   rotates in a different space and came out turquoise). A same-document fragment
   ref has no such ambiguity. The ramp sets the rest level on its own — do not add
   a brightness() here; hover keeps its own lift. Four levels, not a smooth ramp:
   a primitive monitor has few of them, and that is the look. */
:root {
    --phosphor: url(#phosphor);
}

/* App/product icons in the About sections: standardized 64×64 box + same dim phosphor (no frame, no hover) */
.post-content img {
    width: 64px;
    height: 64px;
    object-fit: contain; /* square icons fill it; non-square logos (softdrum) fit without distortion */
    filter: var(--phosphor);
}

.screenshot-gallery img {
    display: block; /* kill inline baseline gap */
    max-width: 100%;
    height: auto;
    border: 1px solid rgba(109, 253, 96, 0.2);
    filter: var(--phosphor); /* honest "dim monitor" at rest */
    transition: border-color 0.2s ease, box-shadow 0.2s ease; /* frame fades; the filter cannot tween from url() to none, it cuts */
}

.screenshot-gallery a {
    border-bottom: none; /* image links: no dotted link-underline under the thumbnail */
}

.screenshot-gallery a:hover { box-shadow: none; } /* drop the theme's generic link glow — keep one clean effect */

.screenshot-gallery a:hover img,
.screenshot-gallery a:focus img {
    border-color: rgba(109, 253, 96, 0.85);
    box-shadow: 0 0 10px rgba(109, 253, 96, 0.35);
    filter: none; /* hover pulls the real image up out of the phosphor */
}

/* Code blocks */
code {
    display: block;
    font-size: 0.8em;
    padding: 25px 20px;
    margin: 15px 0;
    background: rgba(109, 253, 96, 0.05);
    border-left: 1px solid rgba(109, 253, 96, 0.3);
    border-right: 1px solid rgba(109, 253, 96, 0.3);
    color: #6dfd60;
    text-shadow: 0 0 3px #6dfd60;
    overflow-x: auto;
    word-break: break-all;
}

/* Download links and requirements */
.download-link {
    padding: 5px 10px;
    border: 1px solid rgba(109, 253, 96, 0.5);
    display: inline-block;
    margin-right: 10px;
}

.requirements {
    opacity: 0.7;
    font-size: 0.9em;
    /* "Mac OS X 10.2" is one name and "10.4 - 10.14" is one range; the browser
       sees only spaces and breaks mid-phrase. Forbid it - the whole spec moves
       to the next line intact instead. */
    white-space: nowrap;
}

/* ============================================
   RESPONSIVE
   ============================================ */
@media screen and (max-width: 850px) {
    .contentbox {
        width: 95%;
        flex-direction: column;
    }

    #sidebar {
        width: 100%;
        border-bottom: 1px solid #6dfd60;
    }

    /* Stacked, the vertical menu burned ~270px to show five words. Lay it out
       as one wrapping row instead. The "> " prompt marks come off: in a row
       they read as a breadcrumb and collide with the one in the h1. */
    #widgets { padding-top: 0; }
    #widgets-main-title { padding: 10px 15px; }

    /* The channel strip must never break, at any width. nowrap forbids it; the gap
       is tightened and the type scales with the viewport below ~400px so the five
       items always fit rather than wrapping or clipping. 3.5vw keeps 320px legal;
       at 393px it works out to 13.8px, which is indistinguishable from 14. */
    #widgets ul {
        display: flex;
        flex-wrap: nowrap;
        gap: 0 6px;
        padding: 0;
        white-space: nowrap;
        font-size: min(14px, 3.5vw);
    }

    #widgets li { margin-bottom: 0; }
    #widgets li:before { content: none; }

    /* The longest breadcrumb is 32 chars ("barnholt.net > sw > screensavers").
       At 375px that has ~316px to live in. The 3px letter-spacing dominates at
       this size - keeping it would force the type below the body size to fit -
       so both come down together and the title stays on one line. */
    .pagetitle {
        font-size: 1em;
        letter-spacing: 1px;
    }

    /* Kill the vignette. Its ellipse is sized to the viewport, so the dark ring
       always lands on the outer edges of the window — on a wide screen that is
       the empty backdrop either side of the 800px box, but here the content IS
       the viewport, and the ring dimmed the first nav item and both ends of the
       breadcrumb (measured 0.63 black over them at 375px). Nothing to frame on
       a phone, so there is nothing for it to do. */
    body:before { content: none; }

    /* Drop the file size where space is tight: without it 10 of the 11 download
       rows sit beside their button instead of wrapping. The size still ships in
       the markup, so it is there on a wide screen and for anything reading the
       page. */
    .requirements .size { display: none; }
}

/* Lighter glow on small screens */
@media screen and (max-width: 600px) {
    body, h1, h2, p, li, a {
        text-shadow: 0 0 3px #6dfd60;
    }
}

/* ============================================
   AUDIO PLAYER (audio page - built by js/player.js)
   ============================================ */
#player {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999; /* above the vignette, which sits at 9998 */
    background: #000000;
    border-top: 1px solid rgba(109, 253, 96, 0.4);
    padding: 8px 16px 10px;
    font-size: 0.85em;
    line-height: 1.5;
}

/* keep the footer clear of the fixed bar once it exists */
body.has-player #footer {
    padding-bottom: 90px;
}

.pl-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 800px;
    max-width: 100%;
    margin: 0 auto;
}

/* Responsive dot leader — the CSS equivalent of boot.js's row() dots */
.pl-lead {
    flex: 1;
    border-bottom: 1px dotted rgba(109, 253, 96, 0.45);
    margin-bottom: 4px;
}

.pl-state { letter-spacing: 2px; }
.pl-track { font-weight: bold; }
.pl-meta { opacity: 0.8; white-space: nowrap; }

/* Same block cursor as the boot log: blinks while playing, held static otherwise */
.pl-cur {
    display: inline-block;
    width: .55em;
    height: 1em;
    background: currentColor;
    vertical-align: -2px;
    opacity: .25;
}

#player.playing .pl-cur {
    opacity: 1;
    animation: blink 1.6s ease-in-out infinite;
}

.pl-btn {
    background: none;
    border: 1px solid rgba(109, 253, 96, 0.4);
    color: #6dfd60;
    font: inherit;
    line-height: 1.6;
    padding: 0 8px;
    cursor: pointer;
}

.pl-btn:hover {
    background: #6dfd60;
    color: #000000;
    text-shadow: none;
}

.pl-prog {
    flex: 1;
    height: 14px;
    border: 1px solid rgba(109, 253, 96, 0.4);
    position: relative;
    cursor: pointer;
}

.pl-fill {
    display: block;
    height: 100%;
    width: 0;
    background: #6dfd60;
}

/* Black gutters overlaid on the fill, so it reads as [████░░░░] rather than a smooth bar */
.pl-prog:after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(90deg, transparent 0 7px, #000000 7px 9px);
}

@media (prefers-reduced-motion: reduce) {
    #player.playing .pl-cur { animation: none; }
}

/* ============================================
   BOOT LOG (landing/index self-test)
   ============================================ */
#boot-log {
    min-height: 520px;
    margin: 0;
    white-space: pre-wrap;
    font-family: inherit;
    line-height: 1.85;
    color: #6dfd60;
    text-shadow: 0 0 3px #6dfd60;
    opacity: 0.4; /* recede: ambient telemetry, not a navigable element */
}

/* Blinking block cursor trailing the last character */
#boot-log::after {
    content: "";
    display: inline-block;
    width: .62em;
    height: 1.05em;
    vertical-align: -2px;
    margin-left: 2px;
    background: currentColor;
    box-shadow: 0 0 5px rgba(75, 255, 75, .5);
    animation: blink 1.6s ease-in-out infinite;
}

/* Gentle pulse rather than a hard on/off blink */
@keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: .15; }
}

/* Reduced motion: full log rendered instantly, cursor held static */
@media (prefers-reduced-motion: reduce) {
    #boot-log::after { animation: none; }
}
