/* =========================================================================
   Biloou — photobooth
   Same neo-brutalist system as the rest of the site, arranged as a tool:
   a board that keeps the middle of the screen and controls that stay out
   of its way.

   The board itself is a <canvas>. Nothing in here styles what is drawn on
   it — that is all in assets/js/photobooth.js, because the download has to
   look like the screen and a stylesheet cannot reach into a PNG.
   ========================================================================= */

:root {
    --ink:     #141210;
    --paper:   #FFF8EC;
    --paper-2: #FFEFD6;
    --shade:   #E9E2D5;
    --yellow:  #FFE04B;
    --cyan:    #6BE5E0;
    --pink:    #FF6FB5;
    --lime:    #C6FF5C;
    --orange:  #FF8A3D;
    --purple:  #B39BFF;
    --danger:  #D8362A;

    --border: 3px solid var(--ink);
    --sh-sm: 3px 3px 0 var(--ink);
    --sh:    6px 6px 0 var(--ink);

    --font-display: "Arial Black", "Archivo Black", "Helvetica Neue", Impact, system-ui, sans-serif;
    --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-mono: "JetBrains Mono", "Cascadia Mono", Consolas, "Courier New", monospace;

    --bar-h: 4.25rem;
    --panel-w: 23rem;
}

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

[hidden] { display: none !important; }

html, body { height: 100%; }

body.pb-body {
    background: var(--shade);
    background-image:
        linear-gradient(rgba(20, 18, 16, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(20, 18, 16, 0.05) 1px, transparent 1px);
    background-size: 26px 26px;
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;

    /* The tool fills the window and nothing about it scrolls sideways. svh
       rather than vh: on a phone 100vh is the height with the browser chrome
       hidden, so a page sized to it is always exactly one address bar too
       tall. */
    height: 100svh;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    overflow: hidden;
}

a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 {
    font-family: var(--font-display);
    font-weight: 900;
    line-height: 1.02;
    letter-spacing: -0.015em;
    text-transform: uppercase;
}

:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    top: -100px; left: 1rem;
    z-index: 99;
    padding: 0.6rem 1rem;
    background: var(--yellow);
    border: var(--border);
    box-shadow: var(--sh-sm);
    font-weight: 800;
}
.skip-link:focus { top: 0.75rem; }

/* -------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------- */
.pb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    background: var(--paper);
    border: var(--border);
    box-shadow: var(--sh-sm);
    font-weight: 800;
    font-size: 0.9rem;
    line-height: 1.2;
    cursor: pointer;
    transition: transform 0.08s ease, box-shadow 0.08s ease;
    white-space: nowrap;
}
.pb-btn:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--ink); }
.pb-btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--ink); }
.pb-btn[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: var(--sh-sm); }

.pb-btn--go { background: var(--yellow); }
.pb-btn--ghost { background: transparent; }
.pb-btn--quiet { background: var(--ink); color: var(--paper); }
.pb-btn--danger { background: var(--danger); color: #fff; }
.pb-btn--wide { width: 100%; }

.pb-icon {
    width: 2.25rem;
    height: 2.25rem;
    display: inline-grid;
    place-items: center;
    background: var(--paper);
    border: var(--border);
    box-shadow: var(--sh-sm);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}
.pb-icon[disabled] { opacity: 0.35; cursor: not-allowed; }
.pb-icon:not([disabled]):active { transform: translate(2px, 2px); box-shadow: none; }

/* -------------------------------------------------------------------------
   Top bar
   ------------------------------------------------------------------------- */
.pb-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem clamp(0.75rem, 2vw, 1.25rem);
    background: var(--paper);
    border-bottom: var(--border);
    min-height: var(--bar-h);
}

/* The word BILOOU stays at every width. A mark on its own is a mystery, and
   the one thing a stranger who landed here from a shared PNG needs is to know
   whose page this is. */
.pb-bar__brand { flex: none; }

.pb-bar__title {
    font-family: var(--font-display);
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    font-size: clamp(0.95rem, 2.2vw, 1.2rem);
    line-height: 1.05;
    display: flex;
    flex-direction: column;
    padding-left: 0.75rem;
    border-left: var(--border);
    min-width: 0;
}

.pb-bar__note {
    font-family: var(--font-mono);
    font-size: 0.6rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.6;
}

.pb-bar__actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* -------------------------------------------------------------------------
   Shell: board on the left, tools on the right
   ------------------------------------------------------------------------- */
.pb-app {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--panel-w);
    min-height: 0;
}

.pb-noscript {
    padding: 1.25rem;
    margin: 1.25rem;
    background: var(--yellow);
    border: var(--border);
    box-shadow: var(--sh);
    max-width: 44rem;
}

/* -------------------------------------------------------------------------
   Stage
   ------------------------------------------------------------------------- */
.pb-stage {
    position: relative;
    display: flex;
    padding: clamp(0.75rem, 2vw, 1.5rem);
    min-height: 0;
    min-width: 0;

    /* A tall strip is held to a workable width rather than shrunk to fit the
       window (see layout() in photobooth.js), so the stage has to be able to
       scroll past the bottom of it. Sideways it never does. */
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
}

/* Centred with auto margins, not with justify-content — see the note in
   photobooth.php. Auto margins collapse to nothing when the content is bigger
   than the box, so the top of a long strip stays reachable. */
.pb-stage__fit {
    margin: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
}

/* Sized in pixels by JS, from the chosen template's own proportions and
   whatever room the stage has. Doing it in script rather than with
   `aspect-ratio` plus two max-* clamps means one rule decides the size
   instead of three interacting ones, and the canvas backing store is set from
   the same number. */
.pb-stage__frame {
    position: relative;
    flex: none;
    box-shadow: 10px 10px 0 rgba(20, 18, 16, 0.35);
}

/* No CSS border here, deliberately. With box-sizing: border-box a 3px border
   makes the canvas content box six pixels narrower than the element, while the
   backing store is sized from the element — so everything drawn would be
   stretched by 1.4% and every pointer coordinate would be off by the same. The
   board's outer frame is drawn inside renderTo() instead, which also means it
   is part of the saved PNG rather than a browser decoration around it. */
.pb-board {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--paper);

    /* Without this a finger on a sticker scrolls the page instead of moving
       the sticker, and preventDefault() on pointerdown does not help: a touch
       scroll is decided before that runs. */
    touch-action: none;
    cursor: default;
}
.pb-board:focus-visible { outline-offset: 4px; }

.pb-status {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.7;
    text-align: center;
    min-height: 1.2em;
}

/* The call to action while every frame is empty. Sits over the board rather
   than replacing it, so the shape you are about to fill is already visible. */
.pb-empty {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 0.75rem;
    padding: 1.25rem;
    text-align: center;
    background: rgba(255, 248, 236, 0.86);
}

.pb-empty__lead {
    font-family: var(--font-display);
    font-size: clamp(1.1rem, 3vw, 1.6rem);
    text-transform: uppercase;
}

.pb-empty__buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }

.pb-empty__note {
    font-size: 0.8rem;
    max-width: 22ch;
    opacity: 0.75;
}

/* Shown while files are being dragged anywhere over the window. */
.pb-drop {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: rgba(255, 224, 75, 0.9);
    border: 6px dashed var(--ink);
    font-family: var(--font-display);
    font-size: clamp(1.1rem, 4vw, 2rem);
    text-transform: uppercase;
    pointer-events: none;
    z-index: 3;
}

/* -------------------------------------------------------------------------
   Panel
   ------------------------------------------------------------------------- */
.pb-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--paper);
    border-left: var(--border);
}

.pb-sheet { display: none; }

.pb-tabs {
    display: flex;
    overflow-x: auto;
    scrollbar-width: none;
    border-bottom: var(--border);
    background: var(--paper-2);
    flex: none;
}
.pb-tabs::-webkit-scrollbar { display: none; }

.pb-tab {
    flex: 1 0 auto;
    padding: 0.65rem 0.7rem;
    background: transparent;
    border: 0;
    border-right: 1px solid rgba(20, 18, 16, 0.18);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
}
.pb-tab[aria-selected="true"] {
    background: var(--ink);
    color: var(--paper);
}

.pb-panes {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Groups ------------------------------------------------------------------- */
.pb-group { display: flex; flex-direction: column; gap: 0.55rem; }

.pb-group__title {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    opacity: 0.6;
}

.pb-note {
    font-size: 0.78rem;
    line-height: 1.45;
    opacity: 0.75;
}

.pb-row {
    display: grid;
    grid-template-columns: 5.5rem minmax(0, 1fr);
    align-items: center;
    gap: 0.5rem;
}

.pb-row__label {
    font-size: 0.75rem;
    font-weight: 700;
}

.pb-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 700;
}
.pb-field select,
.pb-field input[type="text"],
.pb-input {
    width: 100%;
    padding: 0.45rem 0.55rem;
    background: #fff;
    border: 2px solid var(--ink);
    font-size: 0.85rem;
    font-weight: 500;
}

/* 16px exactly below 700px: anything smaller makes iOS Safari zoom the page on
   focus and never zoom back. */
@media (max-width: 700px) {
    .pb-field select,
    .pb-field input[type="text"],
    .pb-input { font-size: 16px; }
}

input[type="range"] {
    width: 100%;
    accent-color: var(--ink);
}

/* Grids of choices --------------------------------------------------------- */
.pb-grid {
    display: grid;
    gap: 0.4rem;
}
.pb-grid--templates { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pb-grid--tiles     { grid-template-columns: repeat(auto-fill, minmax(4.2rem, 1fr)); }
.pb-grid--emoji     { grid-template-columns: repeat(auto-fill, minmax(2.6rem, 1fr)); }
.pb-grid--shapes    { grid-template-columns: repeat(auto-fill, minmax(3.4rem, 1fr)); }
.pb-grid--swatches  { grid-template-columns: repeat(auto-fill, minmax(2.2rem, 1fr)); }

.pb-pick {
    display: grid;
    gap: 0.25rem;
    justify-items: center;
    padding: 0.4rem 0.25rem;
    background: var(--paper);
    border: 2px solid var(--ink);
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1.1;
    text-align: center;
    text-transform: uppercase;
    cursor: pointer;
    word-break: break-word;
}
.pb-pick[aria-pressed="true"] {
    background: var(--yellow);
    box-shadow: var(--sh-sm);
}

.pb-pick__art {
    display: grid;
    place-items: center;
    width: 100%;
    height: 2.4rem;
}
.pb-pick__art svg { width: 100%; height: 100%; }

.pb-emoji {
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    padding: 0;
    background: var(--paper);
    border: 2px solid var(--ink);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}
.pb-emoji:hover { background: var(--yellow); }

.pb-swatch {
    aspect-ratio: 1;
    padding: 0;
    border: 2px solid var(--ink);
    cursor: pointer;
}
.pb-swatch[aria-pressed="true"] { box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 6px var(--ink); }

.pb-colour {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* A grid inside a flex item keeps its min-content width unless it is told
   otherwise, and a grid of squares has a very small one — the swatches came out
   stacked in a single column. Same trap as the `minmax(0, 1fr)` note in the
   dashboard. */
.pb-colour .pb-grid--swatches {
    flex: 1;
    min-width: 0;
}
.pb-colour input[type="color"] {
    width: 2.4rem;
    height: 2.1rem;
    padding: 0;
    background: none;
    border: 2px solid var(--ink);
    cursor: pointer;
}

/* Frame slots -------------------------------------------------------------- */
.pb-slots {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.pb-slot {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: 0.6rem;
    align-items: center;
    padding: 0.45rem;
    background: var(--paper);
    border: 2px solid var(--ink);
}
.pb-slot.is-selected { background: var(--yellow); box-shadow: var(--sh-sm); }

.pb-slot__thumb {
    width: 3.4rem;
    height: 3.4rem;
    border: 2px solid var(--ink);
    background: var(--shade) center / cover no-repeat;
    display: grid;
    place-items: center;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    font-weight: 700;
    cursor: pointer;
}

.pb-slot__body { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.pb-slot__name {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.pb-slot__actions { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.pb-slot__actions .pb-btn { padding: 0.28rem 0.5rem; font-size: 0.72rem; box-shadow: none; }

/* Layer list --------------------------------------------------------------- */
.pb-layers { display: flex; flex-direction: column; gap: 0.3rem; }

.pb-layer {
    display: grid;
    grid-template-columns: 1.8rem minmax(0, 1fr) 1.8rem;
    gap: 0.4rem;
    align-items: center;
    padding: 0.35rem 0.45rem;
    background: var(--paper);
    border: 2px solid var(--ink);
    font-size: 0.78rem;
}
.pb-layer.is-selected { background: var(--cyan); }

.pb-layer__art {
    font-size: 1.05rem;
    text-align: center;
    line-height: 1;
}

.pb-layer__name,
.pb-layer__drop {
    padding: 0.2rem 0;
    background: none;
    border: 0;
    font-size: inherit;
    cursor: pointer;
}

.pb-layer__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
    font-weight: 600;
}

.pb-layer__drop {
    font-size: 0.9rem;
    line-height: 1;
    opacity: 0.6;
}
.pb-layer__drop:hover { opacity: 1; color: var(--danger); }

/* -------------------------------------------------------------------------
   Phone: the panel becomes a sheet over the board
   ------------------------------------------------------------------------- */
@media (max-width: 940px) {
    .pb-app {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr);
        position: relative;
    }

    .pb-panel {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 5;
        max-height: min(68%, 30rem);
        border-left: 0;
        border-top: var(--border);
        box-shadow: 0 -6px 0 rgba(20, 18, 16, 0.12);

        /* Closed, only the handle shows. The board keeps the screen until you
           ask for a control. */
        transform: translateY(calc(100% - 2.9rem));
        transition: transform 0.22s ease;
    }
    .pb-panel.is-open { transform: translateY(0); }

    @media (prefers-reduced-motion: reduce) {
        .pb-panel { transition: none; }
    }

    .pb-sheet {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.5rem;
        width: 100%;
        height: 2.9rem;
        flex: none;
        padding: 0;
        background: var(--yellow);
        border: 0;
        border-bottom: var(--border);
        font-family: var(--font-mono);
        font-size: 0.72rem;
        font-weight: 700;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        cursor: pointer;
    }
    .pb-sheet__grip {
        width: 2.5rem;
        height: 0.35rem;
        background: var(--ink);
    }

    /* Room under the board for the closed handle, so the bottom of a strip is
       never sitting behind it. */
    .pb-stage { padding-bottom: 3.6rem; }

    /* Bigger targets for a thumb. The geometry does not change — only the
       thing you grab. */
    .pb-btn { padding: 0.55rem 0.9rem; }
    .pb-emoji { font-size: 1.5rem; }
}

@media (max-width: 620px) {
    /* The bar wraps rather than dropping anything. Both the brand and the way
       back into the app are how somebody who arrived from a shared PNG works
       out where they are — a narrow screen is not a reason to take either
       away. */
    .pb-bar { flex-wrap: wrap; row-gap: 0.5rem; }
    .pb-bar__title { order: 3; width: 100%; padding-left: 0; border-left: 0; }
    .pb-bar__actions { margin-left: auto; }
}
