body {
    margin:0;
    padding:0;
    overflow: hidden;
    font-family: arial, helvetica;
    background-color: #d8bfd8;
}
.grid {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 0;
}
.grid img {
    position: absolute;
    bottom: -410px;
    width: 1400px;
    left: 50%;
    transform: translateX(-50%);
}
.logo {
    position: absolute;
    height: 50%;
    top: 50%;
    left: 50%;
    transform: translate(-100%,-50%);
    transform-origin: center;
    z-index: 1;
    animation: logo-pulse 4s ease-in-out infinite;
}
/* .grid {
    transform-origin: center;
    animation: grid-float 4s ease-in-out infinite;
} */
@keyframes logo-pulse {
    0%, 100% { transform: translate(-100%,-50%) scale(.85) rotate(10deg); }
    50% { transform: translate(-100%,-50%) scale(1) rotate(-10deg);  }
}
/* @keyframes grid-float {
    0%, 100% { transform: translate(-10%,-10%); }
    50% { transform: translate(0%,0%);  }
} */
.videos {
    transform: rotate(-45deg) skew(15deg, 15deg);
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 2;
    display: none;
}
.videos .item {
    height: 150px;
    box-shadow: -20px 20px 0px #00000011;
    opacity: .9;
    position: absolute;
}
video.item:first-child {bottom:40%;left:30px;}
video.item:nth-child(2) {bottom:25%;right:60px;}
video.item:nth-child(3) {bottom:70%;left:250px;height:100px;}
video.item:nth-child(4) {bottom:50%;right:180px;height:100px;;}
.videos .item {
    transition: transform 1.05s cubic-bezier(.16, .84, .36, 1),
                opacity .7s ease-out;
}
.videos:not(.is-in) .item {
    opacity: 0;
}
.videos:not(.is-in) video.item:first-child,
.videos:not(.is-in) video.item:nth-child(3) {
    transform: translateX(-80vw);
}
.videos:not(.is-in) video.item:nth-child(2),
.videos:not(.is-in) video.item:nth-child(4) {
    transform: translateX(80vw);
}
.videos video.item:nth-child(2) { transition-delay: .09s; }
.videos video.item:nth-child(3) { transition-delay: .18s; }
.videos video.item:nth-child(4) { transition-delay: .27s; }
.plain {
    position: absolute;
    width: 380px;
    height: 743px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 20px;
    overflow: hidden;
    background-color: #ffffff99;
    backdrop-filter: blur(10px);
    /* background-image: url(https://hakim.ma/images/logo.svg); */
    background-size: 50% auto;
    background-repeat: no-repeat;
    background-position: center;
    z-index: 3;
}
.plain .content {
    opacity: 0;
}
.xd {
    position: absolute;
    width: 380px;
    height: 743px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    box-shadow: 0 0 20px rgba(135, 18, 179, 0.3);
    border-radius: 20px;
    z-index: 4;
}
.footer-bar {
    background-color: #8712B3;
    height: 10px;
    width: 100%;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    top: auto;
    z-index: 0;
}
.sidemenu {
    position: absolute;
    width: auto;
    height: 30px;
    line-height: 30px;
    right: 36px;
    top: 50%;
    transform: translateY(-50%);
    cursor: pointer;
    /* .5 put the 13px label at 3.5:1 on the lilac background — below AA.
       .65 measures 5.6:1 and still reads as a deliberately quiet easter egg. */
    opacity: .65;
    z-index: 5;
    transition: transform 0.1s ease-in, opacity 0.1s ease-in;
    /* These are <button>s now: strip the UA chrome so they look like before. */
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    /* `font` is a shorthand and silently resets line-height to normal, which
       drops the label to the top of the 30px box while the icon stays centred.
       Re-declare it after the shorthand. */
    line-height: 30px;
    color: inherit;
    text-align: right;
    margin-top: 5px;
}
.sidemenu:hover,
.sidemenu:focus-visible {
    transform: scale(1.3);
    transform-origin: 92% 218%;
    opacity: 1;
}
.sidemenu:focus-visible {
    outline: 2px solid #8712B3;
    outline-offset: 4px;
    border-radius: 4px;
}
/* Enlarge the pointer target without moving a single pixel of the design.
   The three controls are stacked only 30-38px apart, so growing all of them
   to 44px in every direction would make each one cover its neighbour's label
   and steal its clicks. Each therefore grows only into the empty space next
   to it: the bottom control downwards, the top control upwards, the middle
   one into the 8px gap above it. All end up >= 38px tall, comfortably past
   the 24px WCAG 2.5.8 minimum. */
.sidemenu::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -12px;
    right: -12px;
}
#proto-toggle::before { bottom: -14px; }
#color-toggle::before { top: -8px; }
#howto-toggle::before { top: -14px; }
.sidemenu p {
    line-height: inherit;
    height: inherit;
    margin: 0;
    display: inline-block;
    vertical-align: middle;
    font-size: small;
}
.sidemenu img, .sidemenu span {
    height: 80%;
    vertical-align: middle;
    margin-left: 7px;
}
/* Colophon. Sits in the same right-hand column as the sidemenu (36px inset) so
   all the page furniture shares one edge, and in the bottom-right corner
   because the skewed video collage runs bottom-left to top-right — the two
   corners off that diagonal are the only reliably empty ones. Same quiet
   opacity as the other easter eggs so it reads as an aside, not a headline. */
.colophon {
    position: absolute;
    right: 36px;
    bottom: 32px;
    z-index: 5;
    opacity: .65;
    font-size: small;
    line-height: 1.5;
    max-width: 34ch;
    text-align: right;
    /* Even out the three lines and keep "self-respect." from splitting at its
       own hyphen, which is where the default greedy wrap put it. */
    text-wrap: balance;
}
.colophon .year {
    display: block;
    color: inherit;
    text-underline-offset: 4px;
    font-size: 1.3em;
    letter-spacing: .14em;
    font-weight: bold;
    text-wrap: nowrap;
}
.colophon .note {
    display: block;
    transition: opacity .9s ease;
}
.colophon .note.is-hidden {
    opacity: 0;
}
/* Annotation off the embed's lower-left: arrow on top, caption underneath.
   Both coordinates are clamped, because body has overflow:hidden on desktop —
   anything pushed past a window edge becomes permanently unreachable, and a
   short window is exactly what hid this the first time round.
     top:  sits 200px below centre, but never nearer than 155px to the bottom.
     left: 390px left of centre, but never past the left edge. */
.embed-note {
    position: absolute;
    top: min(calc(50% + 200px), calc(100% - 155px));
    left: max(16px, calc(50% - 390px));
    width: 180px;
    z-index: 5;
    opacity: .65;
    text-align: right;
}
.embed-note-arrow {
    display: block;
    /* margin-left:auto hugs the right edge so the tip lands next to the embed */
    margin: 0 0 2px auto;
    position: relative;
    left: 20px;
    width: 62px;
    height: 58px;
    fill: none;
    stroke: #8712B3;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.embed-note p {
    margin: 0;
    font-size: small;
    line-height: 1.5;
}
.prototype-screen {
    position: absolute;
    z-index: 9;
    width: 860px;
    /* Cap at 90vw. The 42px subtracts this element's own 20px padding and 1px
       border on each side, so the visible box lands on 90vw with the default
       content-box sizing and desktop rendering is untouched. */
    max-width: calc(90vw - 42px);
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 5px;
    box-shadow: 0 0 90px #00000077;
    padding: 20px;
    border: 1px solid #8712B3;
    background-color: #e4e4e4;
    cursor: pointer;
}
.sidemenu.that-face {
    margin-top: -68px;
    text-align: right;
}
.sidemenu.that-face:hover > #help,
.sidemenu.that-face:focus-visible > #help {
    opacity: 1;
}
#help {
    height: 140px;
    position: absolute;
    right: 100%;
    transform: translate(-50%,-30%);
    box-shadow: 2px 2px 0px #00000022;
    border-radius: 5px;
    transition-delay: .5s;
    transition: all 0.1s ease-out 0s;
    opacity: 0;
}
#help:before {
    content:"\A";
    width: 0;
    height: 0;
    border-top: 20px solid transparent;
    border-bottom: 20px solid transparent;
    border-left: 20px solid #ffffff;
    position: absolute;
    left: -15px;
}
.sidemenu.color1 {
    margin-top: -30px;
    /* was line-height: 1em — that squeezed this label's line box to 16px inside
       a 30px button, parking the text above the swatch. */
    text-align: right;
}
.sidemenu.color1 .color{
    width: 24px;
    height: 24px;
    line-height: 100%;
    /* was baseline, which hung the swatch off the text baseline instead of
       centring it like the two icons above. */
    vertical-align: middle;
    display: inline-block;
    background-color: #5D445D;
    border-radius: 100%;
}
.applyColor1 > * {
    mix-blend-mode: luminosity;
}
p.modifier {
    display: none;
}
.applyColor1 .color1 p {
    display: none;
}
.applyColor1 .color1 .color {
    background-color: #00ff00;
}
.applyColor1 .modifier {
    display: inline-block !important;
}
.show-screen {
    display: none;
}
@media (prefers-reduced-motion: reduce) {
    /* The script already skips fetching the background loops in this case;
       !important also beats the inline display:block it would otherwise have
       set, so the collage stays down if the setting is changed mid-session. */
    .videos {
        display: none !important;
    }
    /* The hover pop and the preview fade become instant rather than animated.
       The states themselves are kept — reduced motion means no animation, not
       no feedback. */
    .sidemenu,
    #help,
    .videos .item {
        transition: none;
    }
    .logo {
        animation: none;
    }
}
/* Below this the note would start sitting on top of the embed it points at. */
@media (max-width: 900px) {
    .embed-note {
        display: none;
    }
}
@media (max-width: 629px) {
    /* The XD artboard is a fixed 380x743 canvas, not a fluid layout — XD's
       player can only scale it uniformly, so it can't be stretched to an
       arbitrary phone's width AND height at once without distorting the
       design. Instead of forcing 100%/100dvh (which just pushes that
       mismatch inside the iframe as a gap in XD's own background color),
       size the box to the artboard's real ratio and grow it as large as
       the viewport allows without cropping or distorting. Any leftover
       sliver shows our own background instead of XD's.
       (100vh first as a fallback for browsers without dvh support.) */
    .xd,.plain {
        width: min(100vw, calc((100vh - 50px) * 380 / 743));
        width: min(100vw, calc((100dvh - 50px) * 380 / 743));
        height: calc(100vh - 50px);
        height: calc(100dvh - 50px);
        top: 0;
        transform: translateX(-50%);
        border-radius: 0;
        box-shadow: 0 0;
    }
    .grid,.logo,.sidemenu {
        display: none;
    }
    .videos {
        display: none !important;
    }
    .plain {
        background-color: #d8bfd8;
    }
    /* The colophon becomes the mobile footer bar: fixed height, full width,
       year and rotating note side by side instead of stacked in the corner. */
    .colophon {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        width: 100%;
        height: 50px;
        max-width: none;
        margin: 0;
        padding: 0 16px;
        box-sizing: border-box;
        background-color: #8712B3;
        color: #d8bfd8;
        opacity: 1;
        text-align: left;
        text-wrap: initial;
        z-index: 6;
    }
    .colophon .year {
        flex: 0 0 auto;
    }
    .colophon .note {
        flex: 1 1 auto;
        text-align: right;
        text-wrap: balance;
    }
}
@media (max-width: 1020px) {
    video.item:nth-child(2) {
        bottom: 0%;
        right: 290px;
    }
}
@media (max-width: 900px) {
    video.item:nth-child(2) {
        bottom: 0%;
        right: 280px;
    }
    video.item:nth-child(4) {
        bottom: 50%;
        right: 50px;
    }
}
@media (min-width: 629px) and (max-height: 743px) {
    .xd {
        height: 100%;
        background-color: #fff;
        border-radius: 0;
    }
}