/* ================================================================== *
 *  shaders.css — the {% shader %} live-GLSL embed.
 *  Loaded only on posts with `shaders: true`. The code block reuses the
 *  global `.prose pre` look; this file styles the canvas + controls and
 *  binds them into one bordered box.
 * ================================================================== */

.shader {
    margin: 0;
    border: 2px solid var(--border);
    border-radius: var(--radius);
    background: var(--box);
    overflow: hidden;
}

/* --- Canvas stage ------------------------------------------------- */
.shader__stage {
    position: relative;
    height: var(--shader-h, 280px);
    background:
        repeating-conic-gradient(#0000 0% 25%, #00000008 0% 50%) 50% / 22px 22px;  /* subtle checker until it paints */
}
.shader__canvas {
    display: block;
    width: 100%;
    height: 100%;
    cursor: crosshair;      /* hints that the demo reads the pointer (iMouse) */
}
/* Postfx demos orbit on drag: show a grab cursor and swallow touch gestures so a
   drag rotates the camera instead of scrolling the page. */
.shader.is-postfx .shader__canvas { cursor: grab; touch-action: none; }
.shader.is-postfx .shader__canvas:active { cursor: grabbing; }
/* Control bar, floated over the bottom of the canvas */
.shader__bar {
    position: absolute;
    left: .55rem;
    bottom: .55rem;
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .25rem .3rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: color-mix(in srgb, var(--box) 82%, transparent);
    backdrop-filter: blur(6px);
    font-size: .72rem;
}
.shader__btn {
    display: grid;
    place-items: center;
    width: 1.7rem;
    height: 1.7rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: .8rem;
    line-height: 1;
    cursor: pointer;
    transition: background .12s ease, color .12s ease;
}
.shader__btn:hover { background: var(--accent-soft); color: var(--accent-ink); }
.shader__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.shader__clock {
    padding-inline: .3rem .5rem;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}

/* Compile / link errors — the GPU's own log, mono and legible. Overlays the top
   of the canvas so a live edit that breaks still shows the last working shader
   running behind the message. */
.shader__err {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    margin: 0;
    max-height: 100%;
    overflow: auto;
    padding: .8rem 1.1rem;
    background: color-mix(in srgb, var(--code-bg) 92%, transparent);
    color: #ff9d8a;
    font-family: var(--font-mono);
    font-size: .78rem;
    line-height: 1.5;
    white-space: pre-wrap;
}

/* --- G-buffer channel switch (postfx demos only) ----------------- *
 *  A little segmented row under the canvas: final image vs. the raw albedo /
 *  normal / depth buffers the post-process reads from. Same pill language as the
 *  category filter, sized down to sit quietly inside the shader box.
 * ---------------------------------------------------------------- */
.shader__views {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem;
    padding: .55rem 1rem;
    border-top: 1px solid var(--border);
    background: var(--box);
}
.shader__viewslabel {
    margin-inline-end: .3rem;
    color: var(--ink-soft);
    font-size: .66rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}
.shader__views button {
    font-family: var(--font-mono);
    font-size: .72rem;
    padding: .25em .8em;
    color: var(--ink-soft);
    background: none;
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: pointer;
    transition: background .12s ease, color .12s ease;
}
.shader__views button:hover { color: var(--ink); background: var(--accent-soft); }
.shader__views button[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.shader__views button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --- Caption + code ---------------------------------------------- */
.shader__caption {
    padding: .6rem 1rem;
    border-top: 1px solid var(--border);
    color: var(--ink-soft);
    font-size: .78rem;
}
.shader__code { position: relative; border-top: 2px solid var(--border); }
.shader__file {
    display: block;
    padding: .5rem 1.1rem .1rem;
    background: var(--code-bg);
    color: var(--ink-soft);
    font-size: .68rem;
    letter-spacing: .08em;
    text-transform: uppercase;
}
/* Square off the pre so it sits flush under the filename tab inside the box */
.shader__code pre {
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
}

/* --- Live editor (editable embeds) ------------------------------- *
 *  A transparent <textarea> sits exactly on top of the highlighted <pre>:
 *  the reader edits real text (with a caret) while the colours show through
 *  from behind. Both MUST share identical type metrics or they'd drift apart.
 * ---------------------------------------------------------------- */
.shader__codehead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-inline-end: .6rem;
    background: var(--code-bg);
}
.shader__code--edit .shader__file { padding-block-end: .5rem; }
.shader__revert {
    flex: none;
    font-family: var(--font-mono);
    font-size: .66rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ink-soft);
    background: none;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: .2em .6em;
    cursor: pointer;
    transition: color .12s ease, border-color .12s ease;
}
.shader__revert:hover { color: var(--accent-ink); border-color: var(--accent); }
.shader__revert:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.shader__editor { position: relative; background: var(--code-bg); }
.shader__editor pre,
.shader__editor .shader__input {
    box-sizing: border-box;
    margin: 0;
    padding: 1.1em 1.25em;
    font-family: var(--font-mono);
    font-size: .85rem;
    line-height: 1.6;
    letter-spacing: normal;
    tab-size: 2;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: break-word;
}
.shader__editor pre {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    background: none;
}
/* The <code> inside .prose inherits `font-size: .88em` globally — that would make
   the highlighted text smaller than the textarea and drift the two apart line by
   line (caret lands above the line you clicked). Force it to match the textarea. */
.shader__editor pre code {
    font: inherit;
    letter-spacing: inherit;
    white-space: inherit;
    word-break: inherit;
    overflow-wrap: inherit;
}
.shader__editor .shader__input {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    min-height: 6rem;
    border: 0;
    background: transparent;
    color: transparent;              /* text comes from the highlighted <pre> behind */
    caret-color: var(--code-fg);
    resize: none;
    outline: none;
    overflow: hidden;                /* JS auto-grows height, so no inner scroll */
}
.shader__editor .shader__input::selection { background: color-mix(in srgb, var(--accent) 45%, transparent); }
.shader__editor:focus-within { box-shadow: inset 0 0 0 2px var(--accent); }
