/* ==========================================================================
   Tokens — pulled from the Figma variables and the window component.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Silka is the typeface in the Figma (Atipo Foundry, commercial licence).
   Drop silka-{light,regular,semibold}.woff2 into assets/fonts/ and these
   faces pick up automatically. Until then the stack below renders.
   -------------------------------------------------------------------------- */
@font-face {
    font-family: "Silka";
    src: url("../fonts/silka-light.woff2") format("woff2");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Silka";
    src: url("../fonts/silka-regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Silka";
    src: url("../fonts/silka-semibold.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

/* Tahoma is a system face on Windows only. Self-host a subset as
   assets/fonts/tahoma.woff2 to keep the XP chrome honest on macOS and iOS. */
@font-face {
    font-family: "XP Tahoma";
    src: local("Tahoma"),
         url("../fonts/tahoma.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* --------------------------------------------------------------------------
   --u must be a registered property, not a plain custom property. Unregistered,
   it stays an unresolved token string, so getComputedStyle hands JavaScript
   "min(100vw / 1440, ...)" and parseFloat returns NaN — the drag maths then
   silently assumes a scale of 1 at every viewport.
   -------------------------------------------------------------------------- */
@property --u {
    syntax: "<length>";
    inherits: true;
    initial-value: 1px;
}

/* The unscaled unit. --u is derived from it, so a window body can re-derive a
   smaller --u for its own contents without a self-referential cycle. */
@property --u-base {
    syntax: "<length>";
    inherits: true;
    initial-value: 1px;
}

:root {
    /* --- brand ------------------------------------------------------- */
    --harry-yellow: #edff00;
    --mono-black: #202020;

    /* --- window glass ------------------------------------------------ */
    --glass: rgba(32, 32, 32, 0.85);
    --glass-edge: rgba(255, 255, 255, 0.3);
    --glass-rule: rgba(255, 255, 255, 0.2);
    --glass-inset: rgba(255, 255, 255, 0.1);

    --ink: #ffffff;
    --ink-muted: rgba(255, 255, 255, 0.5);
    --ink-faint: rgba(255, 255, 255, 0.3);

    /* --- progress ---------------------------------------------------- */
    --pill-from: rgba(249, 243, 83, 0.3);
    --pill-to: rgba(249, 243, 83, 0.05);

    /* --- the taskbar -------------------------------------------------- */
    /* The shape of an XP taskbar is the joke and it stays. The colours were
       Microsoft's own Luna values, pixel for pixel, which is trade dress
       rather than homage - so the bar is rebuilt in Harry's palette instead:
       charcoal from the same family as the window glass, with the brand
       yellow doing the work the XP blue used to do. */
    --bar-face: linear-gradient(180deg,
        #3c3c3c 0%, #2f2f2f 5%, #262626 16%,
        #212121 55%, #1b1b1b 92%, #101010 100%);
    --bar-tab: linear-gradient(180deg, #3f3f3f 0%, #353535 40%, #2d2d2d 100%);
    --bar-tab-active: linear-gradient(180deg, #161616 0%, #202020 100%);
    --bar-tab-edge: rgba(0, 0, 0, 0.55);
    --bar-tray: linear-gradient(180deg, #141414 0%, #1d1d1d 35%, #161616 100%);
    --bar-start: linear-gradient(180deg, #f6ff5c 0%, #edff00 45%, #cbdc00 100%);

    /* The restore dialog's title bar. It was the last blue in the chrome; it
       now shares the taskbar's charcoal, and a yellow rule under it is what
       still says "system dialog" rather than "panel". */
    --dialog-bar: linear-gradient(180deg, #3a3a3a 0%, #2a2a2a 45%, #1b1b1b 100%);

    /* --- start menu --------------------------------------------------- */
    /* Luna's white and pale-blue columns, redone in the same greys: the
       programs side a step lighter than the places side, as XP had it. */
    --menu-col: #2a2a2a;
    --menu-col-alt: #1e1e1e;
    --menu-rule: rgba(255, 255, 255, 0.12);
    --menu-edge: #0c0c0c;

    /* --- traffic lights ---------------------------------------------- */
    --light-close: #ff5f57;
    --light-min: #febc2e;
    --light-max: #28c840;

    /* --- geometry ----------------------------------------------------- */
    --taskbar-h: 40px;
    --win-radius: 10px;
    --win-pad: 18;
    --win-bar-h: 40;

    /* --------------------------------------------------------------------
       The scale unit.

       The desktop was authored against a 1440 x 970 frame. --u is a px-valued
       multiplier, so `calc(var(--x) * var(--u))` turns an authored coordinate
       into a real one.

       It fits BOTH axes. Scaling on width alone let the lower windows drop
       below the taskbar on any short viewport - at 1440x800 the media player
       and Clippy both fell off the canvas. Taking the smaller of the two
       ratios means the whole composition is always on screen, whatever the
       window shape.
       -------------------------------------------------------------------- */
    --u-base: min(100vw / 1440, (100dvh - var(--taskbar-h)) / 970);
    --u: var(--u-base);

    /* --------------------------------------------------------------------
       The canvas.

       --u is the smaller of the two axis ratios, so on a wide-but-short
       viewport it is pinned by the height and the composition would only
       occupy 1440 x --u of the width, leaving the rest of the screen empty
       on the right. The windows spread across the canvas instead.

       The canvas widens with the viewport up to 1620 authored units, then
       stops and centres. That ceiling is not arbitrary: spreading pulls
       windows apart, and past roughly 1620 the Services window stops
       overlapping the photo behind it, which the design intends. Raising it
       breaks that overlap - see tests/spread.probe.mjs.
       -------------------------------------------------------------------- */
    --canvas-max: 1620;
    --canvas-w: min(100vw, calc(var(--canvas-max) * var(--u)));
    --canvas-gutter: max(0px, calc((100vw - var(--canvas-w)) / 2));

    /* --- type scale, in authored units ------------------------------- */
    --t-title: 16;
    --t-lead: 14;
    --t-body: 14;
    --t-eyebrow: 10;   /* 8 in the Figma; 10 is the floor for legible UI text */
    --t-micro: 10;

    --font-display: "Silka", "Helvetica Neue", "Segoe UI", system-ui, -apple-system, sans-serif;
    --font-xp: "XP Tahoma", Tahoma, "DejaVu Sans Condensed", Verdana, sans-serif;

    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ==========================================================================
   Reset / base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
}

body {
    margin: 0;
    background: var(--mono-black);
    color: var(--ink);
    font-family: var(--font-display);
    font-size: calc(var(--t-body) * var(--u));
    line-height: 1.4;
    -webkit-font-smoothing: antialiased;
    overflow: hidden; /* the desktop scrolls inside windows, not the page */
}

img,
svg,
video,
picture {
    display: block;
    max-width: 100%;
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

a {
    color: inherit;
}

:where(a, button, [tabindex]):focus-visible {
    outline: 2px solid var(--harry-yellow);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Kept for the taskbar, the dialog label and screen readers, but out of the
   visual composition - used where a window's own controls take the title bar. */
.hxp-visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.hxp-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    background: var(--mono-black);
    color: var(--ink);
    padding: 10px 16px;
    border-radius: 0 0 6px 0;
}
.hxp-skip:focus {
    left: 0;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
