/* Blazor's error UI styling */
#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* Chat panel placeholder: hidden as soon as the AI terminal renders next to it */
.chat-loading:not(:only-child) {
    display: none;
}

/* Inter 800 for the homepage's name build (js/intro), served from this site so the build can start
   at once; the page's own text uses Inter from Google Fonts */
@font-face {
    font-family: "Inter Build";
    font-weight: 800;
    font-style: normal;
    font-display: swap; /* the canvas waits for it (mkIntroDeps); the heading shows a stand-in meanwhile */
    src: url("/fonts/inter-latin-800-normal.woff2") format("woff2");
}

/* the name is drawn in that same file, so the intro (which waits for it) lands on its final width */
.hero-head h1 { font-family: "Inter Build", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }

/* Homepage hero. Desktop: the hero stays put under the header (sticky) and fills the screen; the
   room fills it behind the text, centred at --frame-x (the middle of the space right of the text,
   set by site.js), and the rest of the page (.hero-cover) slides up over it. Phones and short
   landscape screens: name, room, then the rest of the text, scrolling normally. */
/* --still-room: the room's width as a fraction of the still picture (printed by
   tools/render-workshop-still.py) */
/* overflow-x: on a phone the room is edge to edge, and its entrance (scale 1.12) mustn't make the
   page scroll sideways; desktop clips all of it (overflow: hidden, below) */
#hero { --frame-x: .62; --still-room: .6732; position: relative; overflow-x: clip; }
/* the hero's side margin, which the header shares on every page */
:root { --hero-pad: clamp(1.5rem, 5vw, 6rem); }

.hero-cover {
    position: relative;
    z-index: 10;
    box-shadow: 0 -30px 60px rgba(0, 0, 0, .5);
}

/* The workshop: a still image with link pins (a fixed 16:10 picture, so the pins stay over the
   same objects), replaced by the 3D canvas once it runs (js/workshop). */
.workshop {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 10;
}

.workshop-still,
.workshop-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.workshop-still img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.workshop-canvas {
    display: block;
    opacity: 0;
    transition: opacity .6s ease;
    touch-action: manipulation;
}

.workshop[data-state=live] .workshop-canvas {
    opacity: 1;
}

.workshop[data-state=live] .workshop-still {
    opacity: 0;
    visibility: hidden;
    transition: opacity .6s ease, visibility 0s .6s;
}

.hero-namefx,
.hero-loading {
    display: none;
}

.hero-scroll {
    display: none;
}

@media (min-width: 900px) and (min-height: 500px) {
    #hero {
        position: sticky;
        top: 4rem;
        height: calc(100svh - 4rem);
        overflow: hidden;
    }

    /* the text keeps to the left edge (not the centred page container), so on wide screens the room
       gets the rest of the width */
    #hero .hero-section { /* beats the section's max-w-7xl/px utilities, which load later */
        display: flex;
        align-items: center;
        height: 100%;
        max-width: none;
        margin: 0;
        padding: 0 0 0 var(--hero-pad);
    }

    .hero-copy {
        position: relative;
        z-index: 5;
        width: min(38rem, 42%);
    }

    /* dims and pulls back as the page slides over it (--cover, set by site.js) */
    .workshop {
        position: absolute;
        inset: 0;
        aspect-ratio: auto;
        opacity: calc(1 - var(--cover, 0) * .65);
        transform: scale(calc(1 - var(--cover, 0) * .06));
    }

    /* the still picture is centred on --frame-x, as tall as the stage unless the room in it would
       then be wider than the space right of the text (the scene sizes the live room the same way) */
    .workshop-still {
        inset: auto;
        top: 50%;
        left: calc(var(--frame-x) * 100%);
        width: min((100svh - 4rem) * 1.6, 2 * (1 - var(--frame-x)) * 100% * .88 / var(--still-room));
        height: auto;
        aspect-ratio: 16 / 10;
        transform: translate(-50%, -50%);
        -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%);
        mask-image: linear-gradient(90deg, transparent, #000 12%);
    }

    /* the canvas fills the hero; it fades into the grid at the edge of the text column */
    .workshop-canvas {
        -webkit-mask-image: linear-gradient(90deg, transparent calc((2 * var(--frame-x) - 1) * 100%), #000 calc((2 * var(--frame-x) - 1) * 100% + 6vw));
        mask-image: linear-gradient(90deg, transparent calc((2 * var(--frame-x) - 1) * 100%), #000 calc((2 * var(--frame-x) - 1) * 100% + 6vw));
    }

    .hero-scroll {
        position: absolute;
        left: 50%;
        bottom: 22px;
        z-index: 5;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        transform: translateX(-50%);
        text-transform: uppercase;
        pointer-events: none;
    }

    .hero-scroll span {
        width: 1px;
        height: 28px;
        background: linear-gradient(#22d3ee, transparent);
        animation: hero-scroll 1.6s infinite;
    }
}

@keyframes hero-scroll {
    0% { transform: scaleY(0); transform-origin: top; }
    50% { transform: scaleY(1); transform-origin: top; }
    51% { transform-origin: bottom; }
    100% { transform: scaleY(0); transform-origin: bottom; }
}

/* Stacked layout (phones, tablets, short landscape screens): name, room (edge to edge, 4:3, so the
   room is as large as the width allows), its card and links, then the rest of the text */
@media (max-width: 899px), (max-height: 499px) {
    .hero-section {
        display: flex;
        flex-direction: column;
    }

    .hero-copy { display: contents; }
    .hero-head { order: 1; }
    #workshop { order: 2; }
    .ws-card { order: 3; }
    .hero-body { order: 4; margin-top: 1.5rem; }
    .workshop-links { order: 5; }

    .hero-head h1 { margin-bottom: 1rem; }

    .workshop {
        width: calc(100% + 2rem);
        margin-inline: -1rem;
        aspect-ratio: 4 / 3;
    }
}

/* the section's side padding grows to 1.5rem from 640px; the stage still runs edge to edge */
@media (min-width: 640px) and (max-width: 899px), (min-width: 640px) and (max-height: 499px) {
    .workshop {
        width: calc(100% + 3rem);
        margin-inline: -1.5rem;
    }

    .workshop-still img,
    .workshop-canvas {
        -webkit-mask-image: radial-gradient(ellipse 64% 66% at 50% 50%, #000 78%, transparent 100%);
        mask-image: radial-gradient(ellipse 64% 66% at 50% 50%, #000 78%, transparent 100%);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-scroll span { animation: none; }
}

/* The intro (js/intro): while .intro-pending the hero is hidden and the name build draws over it;
   .intro-flying while the built name flies onto the <h1>; .intro-landed while the rest fades in */
/* hidden on screen only (opacity, not visibility), so a screen reader still reads the name */
.intro-pending .hero-head h1,
.intro-flying .hero-head h1 {
    opacity: 0;
}

.intro-pending .hero-kicker,
.intro-pending .hero-body,
.intro-pending .ws-hint,
.intro-pending .hero-scroll {
    opacity: 0;
    pointer-events: none;
}

.intro-pending #workshop {
    opacity: 0;
    transform: scale(1.12);
    pointer-events: none;
}

.intro-landed .hero-kicker,
.intro-landed .hero-body {
    transition: opacity .7s ease .9s;
}

.intro-landed .ws-hint,
.intro-landed .hero-scroll {
    transition: opacity .8s ease 1.4s;
}

.intro-landed #workshop {
    transition: opacity 1.4s ease, transform 2.2s cubic-bezier(.2, .7, .2, 1);
}

.intro-pending .hero-namefx,
.intro-flying .hero-namefx {
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 20;
    pointer-events: none;
    transform-origin: 0 0;
}

.intro-pending .hero-loading {
    display: flex;
    align-items: center;
    gap: 8px;
    position: absolute;
    left: 50%;
    bottom: 18%;
    z-index: 20;
    transform: translateX(-50%);
    white-space: nowrap;
}

.hero-loading span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #22d3ee;
    animation: hero-loading 1s infinite alternate;
}

@keyframes hero-loading {
    from { opacity: .25; }
    to { opacity: 1; }
}

/* Pins label each object on the still image; shown until the scene is live (no JS, no WebGL,
   too slow, or still loading) */
.workshop-pin {
    display: none;
    position: absolute;
    transform: translate(-50%, -50%);
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 8px;
    border-radius: 999px;
    border: 1px solid rgba(34, 211, 238, .45);
    background: rgba(8, 12, 21, .82);
    color: #e8ebf2;
    font: 600 12px Inter, system-ui, sans-serif;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color .2s, background .2s;
}

.workshop:not([data-state=live]) .workshop-pin {
    display: inline-flex;
}

.workshop-links {
    display: none;
    flex-wrap: wrap;
    gap: 8px;
}

@media (max-width: 639px) {
    .workshop[data-state] .workshop-pin {
        display: none;
    }

    /* always listed on phones: it doubles as a quick index of the room, and hiding it once the
       scene starts would move everything below it. One row that swipes sideways, edge to edge. */
    .workshop-links {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        margin-inline: -1rem;
        padding-inline: 1rem;
        -webkit-mask-image: linear-gradient(90deg, transparent, #000 1rem, #000 calc(100% - 2.5rem), transparent);
        mask-image: linear-gradient(90deg, transparent, #000 1rem, #000 calc(100% - 2.5rem), transparent);
    }

    .workshop-links::-webkit-scrollbar { display: none; }
    .workshop-links li { flex: none; }
}

.workshop-pin::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #22d3ee;
    box-shadow: 0 0 8px #22d3ee;
}

.workshop-pin:hover {
    border-color: #22d3ee;
    background: rgba(8, 12, 21, .95);
}

/* ---------------------------------------------------------------- workshop overlay (js/workshop/ui.js) */
.hero-copy {
    transition: opacity .5s ease, transform .6s cubic-bezier(.2, .7, .2, 1);
}

/* hover tag: positioned in stage pixels by the scene */
.ws-tag {
    /* zero-size anchor: only the centred inner pill takes up space, so it never widens the page */
    position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 7;
    pointer-events: none; opacity: 0; transition: opacity .18s ease; will-change: transform;
}
.ws-tag.on { opacity: 1; }
.ws-tag-in {
    position: relative; width: max-content;
    transform: translate(-50%, calc(-100% - 14px));
    display: flex; align-items: center; gap: 10px; padding: 8px 13px 8px 11px; border-radius: 999px;
    background: rgba(8, 12, 21, .9); border: 1px solid rgba(34, 211, 238, .38); white-space: nowrap;
    box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .8), 0 0 24px -8px rgba(34, 211, 238, .5);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.ws-tag-in::after {
    content: ""; position: absolute; left: calc(50% + var(--ax, 0px)); bottom: -6px; width: 9px; height: 9px;
    transform: translateX(-50%) rotate(45deg); background: rgba(8, 12, 21, .95);
    border-right: 1px solid rgba(34, 211, 238, .38); border-bottom: 1px solid rgba(34, 211, 238, .38);
}
.ws-tag b { font: 600 13px Inter, sans-serif; color: #f1f4f9; }
.ws-tag span { font: 500 11.5px "JetBrains Mono", monospace; color: #8b95a9; }
.ws-tag em { font: 600 10.5px "JetBrains Mono", monospace; font-style: normal; color: #22d3ee; border-left: 1px solid rgba(255, 255, 255, .12); padding-left: 10px; }
.ws-tag em[hidden] { display: none; }
.ws-tag.say span { color: #d6f6ff; font-style: italic; }
.ws-tag.demo .ws-tag-in { animation: ws-nudge 1.1s ease-in-out infinite; }
@keyframes ws-nudge { 50% { box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .8), 0 0 34px -4px rgba(34, 211, 238, .75); } }

/* hint bar: bottom-right of the stage */
.ws-hint {
    position: absolute; right: 4%; bottom: 3%; z-index: 5; pointer-events: none;
    display: flex; align-items: center; gap: 16px; font: 500 12px "JetBrains Mono", monospace; color: #6f788b;
    transition: opacity .35s ease;
}
.ws-hint kbd {
    font: 600 10.5px "JetBrains Mono", monospace; color: #b9c1d1; border: 1px solid rgba(255, 255, 255, .14);
    border-bottom-width: 2px; border-radius: 6px; padding: 2px 6px; margin-right: 6px; background: rgba(255, 255, 255, .03);
}
.ws-hint-found { color: #8892a5; padding-left: 16px; border-left: 1px solid rgba(255, 255, 255, .1); }
.ws-hint-found b { color: #22d3ee; font-weight: 600; }
.ws-hint-tap { display: none; }
.ws-focused .ws-hint { opacity: 0; }
@media (hover: none) {
    .ws-hint-k { display: none; }
    .ws-hint-tap { display: inline; }
}

/* keyboard tour: hidden until it receives focus */
.ws-tour {
    position: absolute; left: 2%; bottom: 3%; z-index: 8; display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
    max-width: 96%; padding: 10px 12px; border-radius: 14px; background: rgba(9, 13, 23, .92);
    border: 1px solid rgba(34, 211, 238, .3); font: 500 12px "JetBrains Mono", monospace; color: #8892a5;
}
.ws-tour:not(:focus-within) { clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; white-space: nowrap; padding: 0; border: 0; }
.ws-tour button {
    font: 500 12.5px Inter, sans-serif; color: #dfe5ef; background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .12); border-radius: 999px; padding: 6px 12px; cursor: pointer;
}
.ws-tour button:hover { border-color: rgba(34, 211, 238, .5); }

/* project card: over the hero text on wide screens, below the room on narrow ones */
.ws-card {
    display: none;
    background: linear-gradient(180deg, rgba(14, 19, 32, .92), rgba(9, 13, 23, .94));
    border: 1px solid rgba(255, 255, 255, .09); border-radius: 20px; padding: 22px 26px 24px;
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .05);
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
}
.ws-card.open { display: block; }
/* stacked layout: a sheet over the bottom of the screen, with the room in view above it, so a
   visitor can tap object after object without scrolling */
@media (max-width: 899px), (max-height: 499px) {
    .ws-card.open {
        position: fixed; left: 8px; right: 8px; bottom: calc(8px + env(safe-area-inset-bottom));
        z-index: 45; max-height: 44svh; overflow-y: auto; overscroll-behavior: contain;
        padding: 16px 20px 20px; border-radius: 18px;
    }
    .ws-card-title { font-size: 20px; }
    .ws-card-desc { font-size: 14px; }
}
.ws-card-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.ws-card-back {
    display: inline-flex; align-items: center; gap: 8px; background: none; border: 0; color: #9aa3b6;
    font: 500 13px Inter, sans-serif; cursor: pointer; padding: 6px 0;
}
.ws-card-back:hover { color: #e8ebf2; }
@media (hover: none) { .ws-card kbd { display: none; } } /* no keyboard to press it on */
.ws-card kbd { font: 600 10px "JetBrains Mono", monospace; color: #8a93a6; border: 1px solid rgba(255, 255, 255, .14); border-radius: 5px; padding: 1px 5px; }
.ws-card-stepper { display: flex; align-items: center; gap: 6px; font: 500 12px "JetBrains Mono", monospace; color: #94a3b8; }
.ws-card-stepper button {
    width: 28px; height: 28px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, .1); background: rgba(255, 255, 255, .03);
    color: #c7cedb; cursor: pointer; font: 600 14px Inter, sans-serif;
}
.ws-card-stepper button:hover { border-color: rgba(34, 211, 238, .5); background: rgba(34, 211, 238, .08); }
.ws-card-kicker { font: 500 12px "JetBrains Mono", monospace; color: #22d3ee; margin-bottom: 8px; }
.ws-card-title:focus-visible { outline: none; }
.ws-card-title { font-size: 28px; font-weight: 800; letter-spacing: -.03em; line-height: 1.08; color: #fff; margin-bottom: 10px; outline: none; }
.ws-card-desc { color: #aab2c3; font-size: 15px; line-height: 1.6; margin-bottom: 16px; }
.ws-card-points { display: grid; gap: 9px; margin-bottom: 18px; }
.ws-card-points li { position: relative; padding-left: 22px; color: #c9d0dc; font-size: 14.5px; line-height: 1.5; }
.ws-card-points li::before {
    content: ""; position: absolute; left: 2px; top: .55em; width: 9px; height: 9px; border-radius: 3px;
    border: 1.5px solid #22d3ee; box-shadow: 0 0 10px rgba(34, 211, 238, .5);
}
.ws-card-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 20px; }
.ws-card-chips span {
    font: 500 11.5px "JetBrains Mono", monospace; color: #c4cbda; border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(255, 255, 255, .03); border-radius: 999px; padding: 5px 10px;
}
.ws-card-cta { height: 42px; padding: 0 18px; font-size: 14px; }

@media (min-width: 900px) and (min-height: 500px) {
    .ws-card {
        /* in the text column's place: the same left edge as the max-w-7xl container's content */
        display: block; position: absolute; left: var(--hero-pad); top: 50%; width: min(460px, 38%); z-index: 6;
        opacity: 0; pointer-events: none; transform: translateY(-50%) translateX(-24px);
        transition: opacity .45s ease, transform .6s cubic-bezier(.2, .7, .2, 1);
    }
    .ws-card.open { opacity: 1; pointer-events: auto; transform: translateY(-50%); transition-delay: .15s; }
    .ws-focused .hero-copy { opacity: 0; transform: translateX(-28px); pointer-events: none; }
}
@media (max-width: 899px), (max-height: 499px) {
    .ws-hint { right: auto; left: 4%; font-size: 11px; gap: 10px; }
    .ws-card-points { display: none; }
}
@media (max-width: 560px) {
    .ws-tag:not(.say) span { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .ws-card, .ws-tag, .hero-copy, .workshop-canvas { transition-duration: .01s !important; }
    .ws-tag.demo .ws-tag-in { animation: none; }
}

/* Moving between pages (mkPageFade in site.js): the old page fades out and the new one fades in,
   rising a few pixels into place. The header and the chat panel are layers of their own, so they
   stay where they are. */
@media (prefers-reduced-motion: no-preference) {
    .site-header { view-transition-name: site-header; }
    #chat-panel { view-transition-name: chat-panel; }
    ::view-transition-old(root) { animation: mk-page-out .16s ease both; }
    ::view-transition-new(root) { animation: mk-page-in .34s cubic-bezier(.2, .7, .2, 1) both; }
}
@keyframes mk-page-out { to { opacity: 0; } }
@keyframes mk-page-in { from { opacity: 0; transform: translateY(8px); } }
