/* ==========================================
   OFFLINE - the personal page as an XP desktop
   Window chrome comes from xp-theme.css (.xp-window / .xp-titlebar).
   This file only styles what lives inside the windows.
   ========================================== */

/* Each window's real heading. The titlebar carries the name visually, but a
   screen reader needs a heading it can land on and jump between. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* On a short page the taskbar would float mid-screen with desktop under it, so
   the body fills the viewport and pushes it to the bottom edge. */
.offline-page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.off-main {
    flex: 1;
    padding-top: 6.5rem;
    padding-bottom: 0;
}

.off-intro {
    max-width: 640px;
    margin-bottom: 2.5rem;
}

.off-intro .section-title {
    margin-bottom: 0.75rem;
}

.off-lede {
    font-size: 1.125rem;
    color: var(--text-tertiary);
    line-height: 1.55;
    text-wrap: pretty;
}

/* ---------- The desktop ----------
   Deliberately uneven: three windows of different widths and heights across the
   top, then two full-width shelves. A uniform card grid is the thing to avoid,
   and real desktops are never tidy. */
.desktop {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
    gap: 1.5rem;
    padding-bottom: 4rem;
}

.win {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Rows pair windows of similar height. The note and the playlist are the two
   shortest, the shelf and the phone-shaped clip are the two most visual. Nothing
   spans two rows: that is what left a dead rectangle beside the shelf. */
.win--note { grid-area: 1 / 1 / 2 / 7; }
.win--music { grid-area: 1 / 7 / 2 / 13; }
.win--movies { grid-area: 2 / 1 / 3 / 10; }
.win--player { grid-area: 2 / 10 / 3 / 13; }
.win--pics { grid-area: 3 / 1 / 4 / 13; }

/* Two up: the note and the playlist share a row, the phone-shaped clip takes
   the next one at a width that still reads as a phone. */
@media (max-width: 1000px) {
    .win--note,
    .win--music,
    .win--player,
    .win--movies,
    .win--pics {
        grid-area: auto;
    }

    /* Full-bleed, a 9:16 clip is most of a screen tall. Cap it so the page
       below stays reachable without a long scroll past one video. */
    .mp-screen {
        max-width: 280px;
        margin: 0 auto;
    }

    .win--note,
    .win--music {
        grid-column: span 6;
    }

    .win--player {
        grid-column: span 5;
    }

    .win--movies,
    .win--pics {
        grid-column: span 12;
    }
}

@media (max-width: 720px) {
    .desktop {
        gap: 1.25rem;
    }

    .win {
        grid-column: 1 / -1 !important;
    }
}

/* XP opened windows by scaling them up out of nothing. One orchestrated load,
   staggered by position. The windows are visible without it; this only plays
   on top. */
@keyframes winOpen {
    from {
        opacity: 0;
        transform: scale(0.94) translateY(10px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.win {
    animation: winOpen 0.42s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.win:nth-child(1) { animation-delay: 0.05s; }
.win:nth-child(2) { animation-delay: 0.12s; }
.win:nth-child(3) { animation-delay: 0.19s; }
.win:nth-child(4) { animation-delay: 0.26s; }
.win:nth-child(5) { animation-delay: 0.33s; }

/* ---------- Notepad: currently.txt ---------- */
.np-menu {
    display: flex;
    gap: 0.9rem;
    padding: 0.3rem 0.6rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-secondary);
}

.np-menu u {
    text-decoration-thickness: 1px;
    text-underline-offset: 1px;
}

.np-body {
    flex: 1;
    padding: 0.9rem 0.95rem;
    background: var(--bg-secondary);
}

.np-lines {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.np-line {
    display: grid;
    grid-template-columns: 5.5rem 1fr;
    gap: 0.75rem;
    align-items: baseline;
    font-size: 0.9375rem;
}

.np-line dt {
    color: var(--text-tertiary);
    font-weight: 700;
}

.np-line dd {
    margin: 0;
    color: var(--text-primary);
    line-height: 1.45;
}

/* The caret sits on its own line, which is where a text editor leaves it after
   you finish typing. Attached to the last line it wrapped on its own and read
   as a stray dash. */
.np-caret {
    margin: 0.7rem 0 0;
    font-size: 0.9375rem;
    line-height: 1;
}

.np-status {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.35rem 0.6rem;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

/* ---------- Playlist ---------- */
.pl-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0.7rem;
    background: var(--bg-tertiary);
    border-bottom: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

/* Five bars, each on its own offset, so it reads as sound rather than a loader. */
.eq {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 12px;
}

.eq i {
    display: block;
    width: 3px;
    height: 100%;
    background: var(--accent);
    transform-origin: bottom;
    animation: eqLevel 1.1s ease-in-out infinite;
}

.eq i:nth-child(2) { animation-delay: 0.18s; }
.eq i:nth-child(3) { animation-delay: 0.06s; }
.eq i:nth-child(4) { animation-delay: 0.32s; }
.eq i:nth-child(5) { animation-delay: 0.22s; }

@keyframes eqLevel {
    0%, 100% { transform: scaleY(0.28); }
    50% { transform: scaleY(1); }
}

.pl-list {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
    background: var(--bg-secondary);
}

/* The whole row is the link, so the target is a comfortable 60px tall instead
   of a title-sized sliver. */
.pl-row {
    display: grid;
    grid-template-columns: 1.4rem 44px minmax(0, 1fr) auto;
    gap: 0.6rem;
    align-items: center;
    padding: 0.5rem 0.7rem;
    text-decoration: none;
    color: inherit;
}

.pl-row:hover {
    background: var(--accent-lighter);
}

.pl-row:hover .pl-title,
.pl-row:hover .pl-go {
    color: var(--accent);
}

.pl-go {
    font-size: 0.9rem;
    color: var(--text-muted);
}

.pl-row + .pl-row {
    border-top: 1px solid var(--border-subtle);
}

.pl-num {
    font-size: 0.8125rem;
    color: var(--text-tertiary);
    text-align: right;
}

.pl-art {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border: 1px solid var(--border-color);
    background: var(--bg-tertiary);
}

/* No cover art yet: a sleeve-shaped tile with a record on it, drawn in CSS so
   there is no broken-image icon and nothing to download. */
.art-empty {
    position: relative;
    display: block;
}

.art-empty::after {
    content: '';
    position: absolute;
    inset: 0;
    margin: auto;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--text-muted);
    box-shadow: inset 0 0 0 5px var(--bg-tertiary), inset 0 0 0 6px var(--text-muted);
}

.pl-meta {
    min-width: 0;
}

.pl-title {
    display: block;
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.3;
}

.pl-artist {
    display: block;
    font-size: 0.8125rem;
    color: var(--text-tertiary);
}

.pl-foot {
    margin: 0;
    padding: 0.45rem 0.7rem 0.5rem;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

/* ---------- Folder toolbar (movies, pictures) ---------- */
.fld-bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.35rem 0.7rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

.fld-bar span {
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

/* ---------- Movies ----------
   It is a top five, so five across on desktop: auto-fit would drop the fifth
   onto its own line and leave the shelf looking half empty. */
.mv-grid {
    list-style: none;
    margin: 0;
    padding: 1rem;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 1rem;
    background: var(--bg-secondary);
}

@media (max-width: 1000px) {
    .mv-grid {
        grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
    }
}

.mv-poster {
    position: relative;
    aspect-ratio: 2 / 3;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    overflow: hidden;
}

.mv-poster img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The rank leads the title line. On the artwork it covered whatever the poster
   put in that corner, which on two of five was a studio banner or the billing. */
.mv-rank {
    flex-shrink: 0;
    min-width: 1.35rem;
    padding: 0.05rem 0.3rem;
    background: linear-gradient(180deg, #FB8E39 0%, #EC7A22 100%);
    color: #3a1c0b;
    border: 1px solid #B4550A;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.35;
    text-align: center;
}

.mv-title {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0.55rem 0 0.15rem;
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.3;
}

.mv-why {
    margin: 0;
    font-size: 0.8125rem;
    color: var(--text-tertiary);
    line-height: 1.45;
    text-wrap: pretty;
}

/* Empty poster: a filmstrip drawn with a repeating gradient, kept faint so five
   of them in a row read as waiting rather than as the design. */
.poster-empty::before,
.poster-empty::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 12px;
    opacity: 0.45;
    background:
        repeating-linear-gradient(
            180deg,
            transparent 0 6px,
            var(--border-color) 6px 12px
        );
}

.poster-hint {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 0.75rem;
}

.poster-empty::before { left: 0; }
.poster-empty::after { right: 0; }

/* ---------- Media player ---------- */
/* Where the capped clip is narrower than its window, the strip either side is
   painted dark so it reads as letterboxing, the way any player handles portrait
   video, rather than as the window showing through. The bar and the note below
   paint over this with their own backgrounds. */
.mp {
    display: flex;
    flex-direction: column;
    flex: 1;
    background: #14171b;
}

/* The clip is a vertical Short. A 16:9 frame would letterbox it into two black
   bars, so the player is the shape of the thing it plays. Its width comes from
   the grid on desktop and from a cap once the windows stack. */
.mp-screen {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 9 / 16;
    padding: 0;
    border: 0;
    background: #14171b;
    cursor: pointer;
    overflow: hidden;
}

.mp-screen img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.85;
    transition: opacity 0.25s ease-out;
}

.mp-screen:hover img {
    opacity: 1;
}

.mp-play {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(180deg, #FB8E39 0%, #EC7A22 100%);
    color: #3a1c0b;
    border: 1px solid #B4550A;
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.5), 0 2px 8px rgba(0, 0, 0, 0.5);
    font-size: 1.4rem;
    line-height: 1;
    padding-left: 4px;
    transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.mp-screen:hover .mp-play {
    transform: scale(1.08);
}

.mp-screen iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

/* No clip wired up yet. */
.mp-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    color: #c9ccd2;
    font-size: 0.8125rem;
    text-align: center;
}

.mp-bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.7rem;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

.mp-note {
    margin: 0;
    padding: 0.6rem 0.7rem 0.7rem;
    background: var(--bg-secondary);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.8125rem;
    color: var(--text-tertiary);
    line-height: 1.45;
    text-wrap: pretty;
}

.mp-seek {
    flex: 1;
    height: 6px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
}

.mp-seek i {
    display: block;
    width: 22%;
    height: 100%;
    background: var(--accent);
}

/* ---------- Pictures ---------- */
/* Thumbnails in an XP folder are a fixed size and pack from the left, they do
   not stretch to fill the window. Flex wrap gives exactly that. */
.pic-grid {
    list-style: none;
    margin: 0;
    padding: 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    background: var(--bg-secondary);
}

.pic-grid > li {
    flex: 0 1 200px;
}

.pic-btn {
    display: block;
    width: 100%;
    padding: 0;
    aspect-ratio: 1 / 1;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    cursor: pointer;
    overflow: hidden;
}

.pic-btn img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.pic-btn:hover img {
    transform: scale(1.05);
}

.pic-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    background: var(--bg-tertiary);
    border: 1px dashed var(--border-color);
    color: var(--text-tertiary);
    font-size: 0.75rem;
    text-align: center;
    padding: 0.5rem;
}

/* Lightbox: native <dialog> so Escape and the top layer come for free. */
/* The global `* { margin: 0 }` reset kills the UA's `margin: auto` on dialog,
   which is what centres a modal. Put it back. */
.lightbox {
    margin: auto;
    max-width: min(92vw, 900px);
    max-height: 90vh;
    padding: 0;
    border: 1px solid #9a5a1e;
    background: var(--bg-secondary);
    box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);
}

/* Only when open: an unqualified display on a dialog beats the UA's
   `dialog:not([open]) { display: none }` and the thing never closes. Column flex
   lets the photo take whatever height the titlebar and caption leave it. */
.lightbox[open] {
    display: flex;
    flex-direction: column;
}

.lightbox::backdrop {
    background: rgba(20, 23, 27, 0.72);
}

.lightbox img {
    display: block;
    width: 100%;
    min-height: 0;
    object-fit: contain;
    background: #14171b;
}

.lb-caption {
    margin: 0;
    padding: 0.6rem 0.75rem 0.7rem;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.45;
    text-wrap: pretty;
}

.lightbox .xp-titlebar {
    position: sticky;
    top: 0;
}

.lb-close {
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* ---------- Taskbar ---------- */
.taskbar {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    padding: 0.3rem 0.5rem;
    background: linear-gradient(180deg, #FB8E39 0%, #EF7C24 100%);
    border-top: 1px solid #B85E12;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.tb-start {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    padding: 0.4rem 1rem 0.4rem 0.7rem;
    background: #ECE9D8;
    color: #9A4708;
    border: 1px solid #B85E12;
    box-shadow: inset 1px 1px 0 #ffffff, inset -1px -1px 0 #aca899;
    font-family: "Pixelify Sans", Tahoma, sans-serif;
    font-size: 1rem;
    font-weight: 700;
    text-decoration: none;
}

.tb-start:hover {
    background: #FDECDD;
}

.tb-flag {
    display: grid;
    grid-template-columns: 6px 6px;
    grid-template-rows: 6px 6px;
    gap: 1px;
}

.tb-flag i {
    display: block;
    background: #9A4708;
}

.tb-tasks {
    display: flex;
    gap: 0.35rem;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.tb-tasks::-webkit-scrollbar {
    display: none;
}

.tb-task {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    padding: 0.4rem 0.7rem;
    background: rgba(255, 255, 255, 0.28);
    color: #3a1c0b;
    border: 1px solid #B85E12;
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.4);
    font-size: 0.75rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}

.tb-task:hover {
    background: rgba(255, 255, 255, 0.5);
}

.tb-tray {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
    margin-left: auto;
    padding: 0.4rem 0.75rem;
    background: rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(184, 94, 18, 0.7);
    color: #3a1c0b;
    font-size: 0.75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
    .tb-tasks {
        display: none;
    }
}

@media (max-width: 768px) {
    .off-main {
        padding-top: 5.5rem;
    }

    .np-line {
        grid-template-columns: 1fr;
        gap: 0.1rem;
    }
}

/* The site has no global reduced-motion rule in styles.css, so this page states
   its own: everything that moves here stops, nothing disappears. */
@media (prefers-reduced-motion: reduce) {
    .win {
        animation: none;
    }

    .eq i {
        animation: none;
        transform: scaleY(0.6);
    }

    .mp-screen img,
    .mp-screen:hover .mp-play,
    .pic-btn img {
        transition: none;
        transform: none;
    }
}
