/* ==========================================================================
   Article pages: the loaded disk's contents shown on a CRT terminal that
   sits on the same desk as the home page. Cassette-futurism skeuomorphism.
   Light source is up and to the left.

   Article content itself renders on a warm "paper-white phosphor" tube so
   text, images, and interactive demos stay easy to read.
   ========================================================================== */

/* Desk surface, plate header, and shared hardware details live in desk.css,
   loaded before this file. This file adds the monitor and article content. */

@layer base, desk, monitor, content, blocks, effects;

* {
    box-sizing: border-box;
}

@layer base {
    :root {
        /* The tube: warm paper-white phosphor. */
        --phosphor: #e9e5d3;
        --ink: #2a2f33;
        --ink-dim: #5f6156;
        --link: #9d4a11;
        --link-bright: #c9611b;

        /* Dark terminal blocks (code, and the 404 screen). */
        --term-bg: #23261e;
        --term-text: #e6d9b4;
        --term-green: #7cd88a;
    }

    /* for images or canvas elements that need "pixel" style rendering when scaled */
    .pixel {
        image-rendering: optimizeSpeed;
        image-rendering: -moz-crisp-edges;
        image-rendering: -webkit-optimize-contrast;
        image-rendering: -o-crisp-edges;
        image-rendering: pixelated;
        -ms-interpolation-mode: nearest-neighbor;
    }

    .interactive {
        cursor: pointer;
    }
}

/* ==========================================================================
   The terminal: a putty-cased CRT monitor sunk into the desk view.
   ========================================================================== */

@layer monitor {
    main.monitor {
        --bezel: clamp(10px, 2.6vw, 26px);
        position: relative;
        inline-size: min(100% - clamp(12px, 5vw, 64px), 940px);
        margin: clamp(14px, 2.4vw, 30px) auto clamp(18px, 3vw, 36px);
        padding: 0 var(--bezel);
        border-radius: clamp(12px, 1.8vw, 20px);
        background:
            var(--noise-img),
            linear-gradient(165deg, #d2c8b0 0%, var(--putty) 42%, #9c9276 100%);
        background-size: 140px 140px, 100% 100%;
        background-blend-mode: soft-light, normal;
        box-shadow:
            inset 0 1px 0 rgb(255 255 255 / 0.45),
            inset 0 -2px 3px rgb(0 0 0 / 0.2),
            inset -1px 0 2px rgb(0 0 0 / 0.12),
            0 1px 0 rgb(255 255 255 / 0.07),
            3px 6px 14px rgb(0 0 0 / 0.35),
            10px 18px 40px rgb(0 0 0 / 0.25);
    }

    /* Top bezel: drive bay (the way back home), model badge, power LED. */
    .monitor-top {
        display: flex;
        align-items: center;
        gap: 12px;
        min-block-size: 44px;
        padding: 6px 14px;
    }

    .monitor-top nav {
        margin-inline-end: auto;
    }

    /* The drive bay is a link: eject the disk to return to the desk. */
    a.eject-bay {
        display: inline-flex;
        align-items: center;
        gap: 9px;
        padding: 4px 0px;
        border-radius: 6px;
        text-decoration: none;
        font-family: var(--font-mono);
        font-size: 0.62rem;
        font-weight: 700;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: #55503f;
        text-shadow: 0 1px 0 rgb(255 255 255 / 0.3);
    }

    a.eject-bay:focus-visible {
        outline: 2px dashed var(--led-amber);
        outline-offset: 2px;
    }

    /* The slot does not clip: the disk stands proud of its top edge. */
    .bay-slot {
        position: relative;
        display: inline-block;
        inline-size: clamp(58px, 40vw, 160px);
        block-size: 15px;
        border-radius: 3px;
        background: linear-gradient(180deg, #0b0a08 0%, #191713 70%, #262119 100%);
        box-shadow:
            inset 0 2px 3px rgb(0 0 0 / 0.85),
            0 1px 0 rgb(255 255 255 / 0.3);
    }

    /* The loaded disk, seen edge-on and standing a little proud of the slot.
       It went into the drive shutter-first, so the rim on show is the plain
       trailing edge: a lit upper half-shell, the moulding seam, then the
       lower half falling away into the drive. Shell colour is seeded from the
       article slug, so it matches that article's disk on the home page. */
    .bay-disk {
        position: absolute;
        top: 3px;
        left: 7px;
        right: 7px;
        bottom: 2px;
        z-index: 1;
        border-radius: 1px 1px 0px 0px;
        background:
            var(--noise-img),
            /* Seam between the two half-shells, within the 6px on show. */
            linear-gradient(180deg,
                transparent 3px,
                rgb(0 0 0 / 0.42) 3px 4px,
                transparent 4px),
            /* Hard stops, not a fade: the rim has edges to catch. Shading
               below the seam stays flat, so the rim reads as a flat edge
               sitting in shadow rather than a rounded tube; the recess
               itself is shaded by .bay-slot::after, over the top. */
            linear-gradient(180deg,
                color-mix(in oklab, var(--shell, #33518f), white 18%) 0px,
                color-mix(in oklab, var(--shell, #33518f), white 8%) 3px,
                color-mix(in oklab, var(--shell, #33518f), black 8%) 4px,
                color-mix(in oklab, var(--shell, #33518f), black 14%) 100%);
        background-size: 140px 140px, 100% 100%, 100% 100%;
        background-blend-mode: overlay, normal, normal;
        /* background-blend-mode: soft-light, normal, normal; */
        box-shadow:
            inset 0 1px 0 rgb(255 255 255 / 0.4),
            0 0 3px rgb(0 0 0 / 0.5),
            0 2px 3px rgb(0 0 0 / 0.5);
        transition:
            top 0.3s linear(0, 0.618 4.6%, 1.072 9.7%, 1.358 15.3%, 1.446 18.4%, 1.497 21.7%, 1.512 23.9%, 1.514 26.2%, 1.481 31.5%, 1.421 36.4%, 1.174 53.4%, 1.108 59.5%, 1.059 65.7%, 1.028 71.9%, 1.009 78.9%, 1)
    }

    /* The slot's lip and interior, drawn over the disk: whatever is still in
       the drive sits in shadow, pinning the disk's visible edge to the lip. */
    .bay-slot::after {
        content: '';
        position: absolute;
        inset: 0;
        z-index: 2;
        pointer-events: none;
        border-radius: inherit;
        background: linear-gradient(180deg,
            rgb(0 0 0 / 0%) 0%,
            rgb(0 0 0 / 0%) 38%,
            rgb(0 0 0 / 24%) 58%,
            rgb(22 22 41 / 71%) 100%
        );
    }

    /* Moulded eject button beside the slot. */
    .eject-btn {
        display: inline-grid;
        place-items: center;
        inline-size: 30px;
        block-size: 16px;
        border-radius: 3px;
        font-size: 0.62rem;
        line-height: 1;
        color: #55503f;
        background: linear-gradient(180deg, #d6ccb4, #b3a98f);
        box-shadow:
            inset 0 1px 0 rgb(255 255 255 / 0.5),
            inset 0 -1px 1px rgb(0 0 0 / 0.2),
            0 2px 2px rgb(0 0 0 / 0.35);
    }

    a.eject-bay:hover .eject-btn,
    a.eject-bay:active .eject-btn {
        translate: 0 1px;
        box-shadow:
            inset 0 1px 2px rgb(0 0 0 / 0.3),
            0 1px 1px rgb(0 0 0 / 0.3);
    }

    .monitor-brand {
        font-family: var(--font-mono);
        font-size: 0.6rem;
        letter-spacing: 0.16em;
        text-transform: uppercase;
        color: #5b5442;
        text-shadow: 0 1px 0 rgb(255 255 255 / 0.3);
        white-space: nowrap;
    }

    @media (max-width: 560px) {
        .monitor-brand {
            display: none;
        }
    }

    .power-led {
        inline-size: 9px;
        block-size: 9px;
        border-radius: 50%;
        background: radial-gradient(circle at 35% 30%, #c6ffc2, var(--led-green) 65%);
        box-shadow:
            0 0 7px rgb(110 224 106 / 0.8),
            inset 0 1px 1px rgb(0 0 0 / 0.2);
        transition: background 0.2s ease, box-shadow 0.2s ease;
    }

    /* --------------------------------------------------------------------
       The tube. No overflow clipping here: articles rely on position:sticky
       for scroll-driven demos, which an overflow ancestor would break.
       -------------------------------------------------------------------- */
    .screen {
        position: relative;
        border-radius: clamp(10px, 1.4vw, 18px);
        padding: clamp(16px, 3.5vw, 40px) clamp(12px, 4vw, 46px) clamp(20px, 4vw, 48px);
        color: var(--ink);
        color-scheme: light;
        background:
            var(--noise-img),
            linear-gradient(180deg, #eeeada 0%, var(--phosphor) 45%, #e0dbc6 100%);
        background-size: 140px 140px, 100% 100%;
        background-blend-mode: soft-light, normal;
        box-shadow:
            /* Seam where the tube sits in the case. */
            0 0 0 3px rgb(22 20 14 / 0.6),
            0 0 0 4px rgb(255 255 255 / 0.07),
            /* Curved glass: shading pulls in at every edge. */
            inset 0 2px 10px rgb(0 0 0 / 0.2),
            inset 0 -2px 8px rgb(0 0 0 / 0.12),
            inset 0 0 54px rgb(58 48 24 / 0.12);
    }

    /* Bottom bezel doubles as the page footer: vents (desk.css) on the
       left, the small print (desk.css) screen-printed bottom right. */
    footer.monitor-chin {
        display: flex;
        flex-flow: row-reverse wrap;
        align-items: flex-end;
        gap: 8px 14px;
        padding: 10px 10px 0;
    }

    /* Case screws. */
    .monitor-screw {
        position: absolute;
        inline-size: 8px;
        block-size: 8px;
        border-radius: 50%;
        background:
            linear-gradient(45deg, transparent 42%, #4c463565 44%, #4c463565 56%, transparent 58%),
            radial-gradient(circle at 35% 30%, #ddd3ba24, #91876c26 70%);
        box-shadow:
            inset 0 -1px 1px rgb(0 0 0 / 0.4),
            0px 0px 0.5px 1px rgb(18 18 26 / 51%),
            0px 0px 0px 2px rgba(255, 252, 239, 0.093);
    }
    .screw-tl { inset-block-start: 10px; inset-inline-start: 10px; rotate: 12deg; }
    .screw-tr { inset-block-start: 10px; inset-inline-end: 10px; rotate: 80deg; }
    .screw-bl { inset-block-end: 10px; inset-inline-start: 10px; rotate: -30deg; }
    .screw-br { inset-block-end: 10px; inset-inline-end: 10px; rotate: 55deg; }

    /* --------------------------------------------------------------------
       Dark phosphor variant: used by the 404 terminal.
       -------------------------------------------------------------------- */
    .screen.screen-dark {
        color: var(--term-green);
        color-scheme: dark;
        background:
            var(--noise-img),
            radial-gradient(120% 130% at 30% 0%, #171c15 0%, #0f130e 60%, #0a0d09 100%);
        background-size: 140px 140px, 100% 100%;
        background-blend-mode: soft-light, normal;
    }

    .screen-dark .term {
        margin: 0 auto;
        max-inline-size: 780px;
        min-block-size: 40vh;
        font-family: var(--font-mono);
        font-size: clamp(0.78rem, 0.6rem + 1vw, 1rem);
        line-height: 1.8;
        white-space: pre-wrap;
        overflow-wrap: break-word;
        text-shadow: 0 0 7px rgb(110 224 130 / 0.45);
    }

    .screen-dark .term a {
        color: #b8f0be;
    }

    .term-cursor {
        display: inline-block;
        inline-size: 0.6em;
        block-size: 1em;
        vertical-align: text-bottom;
        background: currentColor;
        box-shadow: 0 0 7px rgb(110 224 130 / 0.7);
    }

    @media (prefers-reduced-motion: no-preference) {
        .term-cursor {
            animation: cursor-blink 1.1s steps(1) infinite;
        }
    }

    @keyframes cursor-blink {
        50% { opacity: 0; }
    }
}

/* ==========================================================================
   Article content, displayed on the tube.
   ========================================================================== */

@layer content {
    article {
        display: block;
        position: relative;
        z-index: 1; /* keeps content in one stacking context below the glass */
        max-width: 780px;
        margin: 0 auto;
        line-height: 1.55;
        accent-color: var(--accent);
    }

    article > p,
    article > ul,
    article > ol,
    article > table,
    article > math {
        margin: 20px 0;
    }

    article a:link,
    article a:visited {
        color: var(--link);
        text-decoration-thickness: 1px;
        text-underline-offset: 2px;
    }

    article a:hover {
        color: var(--link-bright);
    }

    /* Headings printed by the terminal's character generator. */
    article h1,
    article h2 {
        font-family: var(--font-mono);
        font-size: 1.05rem;
        font-weight: 700;
        letter-spacing: 0.18em;
        text-transform: uppercase;
        text-align: left;
        color: var(--ink);
        clear: both;
        margin-top: 3rem;
        margin-bottom: 1rem;
    }

    article > h1::before,
    article > h2::before {
        content: '// ';
        color: var(--accent);
    }

    section {
        display: block;
        margin: 0;
        padding: 0 clamp(0px, 5vw, 60px);
    }

    b {
        font-weight: bold;
    }

    sup {
        font-size: 0.7rem;
        font-weight: normal;
        font-style: normal;
    }

    small {
        font-size: 0.6rem;
        font-weight: normal;
        font-style: normal;
    }

    figcaption {
        text-align: center;
        font-family: var(--font-mono);
        font-size: 0.72rem;
        letter-spacing: 0.04em;
        color: var(--ink-dim);
    }

    .smallIcon {
        margin-left: 4px;
        padding: 0;
        border: none;
    }
}

/* ==========================================================================
   Shared content blocks: code, callouts, media, tables, layout helpers.
   ========================================================================== */

@layer blocks {
    /* Inline code: a faint chip on the phosphor. */
    .code,
    code {
        font-family: var(--font-mono);
        font-size: 0.8rem;
        letter-spacing: 0px;
        background: rgb(58 52 28 / 0.09);
        padding: 0.08em 0.35em;
        border-radius: 3px;
    }

    /* Code blocks: a window into a dark terminal, amber phosphor text. */
    pre .code,
    pre.code,
    pre code {
        display: block;
        white-space: pre-wrap;
        tab-size: 2;
        -moz-tab-size: 2;
        clear: both;
        padding: 9px 12px;
        border-radius: 0 3px 3px 0;
        color: var(--term-text);
        background:
            linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 8%),
            linear-gradient(180deg, #262a20, var(--term-bg));
        border-left: solid 6px var(--accent);
        box-shadow:
            inset 0 1px 4px rgb(0 0 0 / 0.5),
            0 1px 0 rgb(255 255 255 / 0.35);
        margin-top: 0;
        margin-bottom: 2rem;
        text-shadow: 0 0 4px rgb(230 217 180 / 0.25);
    }

    .code .comment,
    code .comment {
        color: var(--term-green);
    }

    /* Callout blocks: keep their semantics, tinted to sit on the tube. */
    .warning {
        display: block;
        background-color: #7e4033;
        color: #f4e8da;
        padding: 15px 20px 15px 15px;
        border-left: 6px solid #e2603d;
        box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.25);
        margin-top: 0;
        margin-bottom: 2rem;
    }

    .warning a:link,
    .warning a:visited {
        color: #ffcfa8;
    }

    .download {
        display: block;
        background-color: #b5c797;
        color: #29321f;
        padding: 15px 20px 15px 15px;
        border-left: 6px solid #5d8f3d;
        box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.12);
        margin-top: 0;
        margin-bottom: 2rem;
    }

    .download a:link,
    .download a:visited {
        color: #2d4d1e;
    }

    aside,
    .aside {
        display: block;
        background-color: #ddd7c3;
        color: var(--ink);
        padding: 15px 20px 15px 15px;
        border-left: 6px solid var(--putty-dark);
        box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.1);
        margin-top: 0;
        margin-bottom: 2rem;
    }

    math {
        display: block;
        background-color: #c3cfc6;
        color: var(--ink);
        padding: 15px 20px 15px 15px;
        border-left: 6px solid #6c8d80;
        box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.1);
        margin: 10px 0;
    }

    /* Media. */
    article canvas,
    article img,
    article video {
        display: block;
        padding: 0;
        max-width: 100%;
        height: auto;
        margin: 10px auto;
    }

    article canvas {
        background: #f0ede1;
    }

    article iframe {
        display: block;
        padding: 4px;
        border: solid 1px var(--putty-dark);
        margin: 10px auto;
    }

    /* Tables. */
    article table,
    article tr,
    article td {
        border-collapse: collapse;
    }

    article th {
        border-collapse: collapse;
        padding: 5px;
        text-align: left;
        font-weight: normal;
        font-size: 1rem;
    }

    table.gridded td,
    table.gridded th {
        border: solid 1px #a29c85;
        font-family: var(--font-mono);
        font-size: 0.8rem;
        letter-spacing: 0px;
        font-weight: normal;
        padding: 3px;
    }

    /* Floating figures. */
    .left {
        display: block;
        float: left;
        clear: left;
        max-width: 500px;
        margin: 10px 40px 10px 0;
    }

    .right {
        display: block;
        float: right;
        clear: right;
        max-width: 500px;
        margin: 10px 0 10px 40px;
    }

    /* within a figure only needs margin to separate from caption */
    figure img,
    figure canvas {
        margin: 0 0 10px;
    }

    /* -- Adjust images for narrow displays, bringing in the floaters */
    @media (max-width: 800px) {
        .left,
        .right {
            display: block;
            float: none;
            clear: none;
            max-width: 100%;
            padding: 15px 0;
            margin-left: auto;
            margin-right: auto;
        }
    }

    /*	allows multiple images to be displayed that will appear on a single line if
        space allows, or spread nicely if not.
    */
    .image-box {
        display: flex;
        width: 100%;
        flex-wrap: wrap;
        justify-content: space-around;
        align-content: flex-start;
        padding-top: 15px;
        padding-bottom: 15px;
    }

    .image-box > * {
        padding: 0;
        margin: 8px;
    }
}

/* ==========================================================================
   Screen effects.
   ========================================================================== */

@layer effects {
    /* Scanlines would be here, but not so sure about the look. */
    /* .screen::before {
        content: '';
        position: absolute;
        inset: 2px;
        z-index: 6;
        border-radius: inherit;
        pointer-events: none;
        background: repeating-linear-gradient(180deg,
            rgba(35, 45, 30, 0) 0 1px,
            transparent 1px 3px);
    } */

    /* Glare from the desk lamp, top-left, on the outside of the glass. */
    .screen::after {
        content: '';
        position: absolute;
        inset: 0;
        z-index: 7;
        border-radius: inherit;
        pointer-events: none;
        background: radial-gradient(90% 420px at 12% -80px,
            rgba(255, 255, 255, 0.604),
            transparent 65%) no-repeat;
    }

    .screen-dark::before {
        background: repeating-linear-gradient(180deg,
            rgb(120 255 150 / 0.045) 0 1px,
            transparent 1px 3px);
    }

    /* ---- Power on / eject ----------------------------------------------- */

    @media (prefers-reduced-motion: no-preference) {
        .screen {
            animation: screen-on 0.5s ease-out;
        }
    }

    @keyframes screen-on {
        0% { filter: brightness(0.15) contrast(1.6) saturate(0.4); }
        55% { filter: brightness(1.25) contrast(1.12); }
        100% { filter: brightness(1) contrast(1); }
    }

    /* Ejecting (leaving via the drive bay link): power down politely. */
    body.is-ejecting .screen {
        filter: brightness(0.06) saturate(0.3);
        transition: filter 0.32s ease-in;
    }

    body.is-ejecting .screen::after {
        opacity: 0;
        transition: opacity 0.32s ease-in;
    }

    body.is-ejecting .power-led {
        background: radial-gradient(circle at 35% 30%, #8a3c34, var(--led-off) 65%);
        box-shadow:
            inset 0 1px 1px rgb(0 0 0 / 0.6),
            0 1px 0 rgb(255 255 255 / 0.3);
    }

    body.is-ejecting .bay-disk {
        top: -30px;
    }
}
