/*
  The Look Wall — chrome for a canvas-rendered kiosk display.

  Almost nothing here paints the wall itself; the canvas does that. This is the fixed viewport
  shell plus the few controls that must remain real DOM to stay focusable and announceable.
  Token values mirror Prism rather than importing it, matching how session-view.css is built.
*/
.gk {
    --navy-deep: #070f24;
    --brand: #204855;
    --brand-hover: color-mix(in srgb, var(--brand) 82%, white);
    --accent: color-mix(in srgb, var(--brand) 48%, white);
    --accent-soft: color-mix(in srgb, var(--brand) 26%, white);
    --text: #f4f7ff;
    --text-dim: rgba(244, 247, 255, 0.68);
    --edge: rgba(255, 255, 255, 0.16);
    --font: "Source Sans Pro", "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    /* One height for every control pill, so the toolbar reads as a single row. */
    --pill-h: 2.35rem;

    /*
      Fixed rather than a tall block: the wall is navigated by camera, not by scrolling, and a
      scrollable body on a kiosk invites accidental rubber-banding on touch frames.
    */
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: var(--navy-deep);
    color: var(--text);
    font-family: var(--font);
    line-height: 1.5;
}

.gk.is-demo-source {
    --navy-deep: #204855;
}

/* The page behind it must not scroll either, or a stray gesture drags the whole document. */
:root:has(.gk),
body:has(.gk) {
    overflow: hidden;
    overscroll-behavior: none;
}

/*
  Several overlays here set `display`, which outranks the UA stylesheet's `[hidden]` rule and
  leaves them on screen after the engine hides them. Restate it as an author rule.
*/
.gk [hidden] {
    display: none !important;
}

.gk-canvas {
    display: block;
    width: 100%;
    height: 100%;
    /* The canvas is the interaction surface; browser panning and text selection only fight it. */
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    cursor: grab;
}

.gk-canvas:active {
    cursor: grabbing;
}

/* ---------- boot ---------- */

.gk-boot {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 1.1rem;
    background: var(--navy-deep);
    color: var(--text-dim);
    font-size: 0.9rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    z-index: 3;
}

.gk-boot p {
    margin: 0;
}

.gk-boot-mark {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--accent) 22%, transparent);
    border-top-color: var(--accent);
    animation: gk-spin 0.9s linear infinite;
}

@keyframes gk-spin {
    to { transform: rotate(360deg); }
}

/* ---------- chrome ---------- */

/*
  The chrome floats over the wall with its controls withdrawn from the start, so an unattended
    screen shows photography rather than an operator toolbar. Holding the logo for five seconds
    brings the controls back. The brand block never leaves: the wall should always say what it is.
*/
.gk-chrome {
    /* One edge for the corner the brand sits in, the corner the invitation sits in, and the
       notch or rounded corner of whatever screen this is. */
    --edge-x: max(clamp(1rem, 3vw, 2.5rem), env(safe-area-inset-left, 0px));
    --edge-y: max(clamp(0.9rem, 2.6vmin, 2rem), env(safe-area-inset-top, 0px));
    position: absolute;
    pointer-events: none;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    padding: var(--edge-y) var(--edge-x) clamp(3rem, 9vmin, 6rem);
    /* A long, eased scrim: dark enough under the type to read over any photo, gone well before the
       first full row of tiles, so the wall still reads edge to edge. */
    background: linear-gradient(to bottom,
        rgba(4, 9, 22, 0.88) 0%,
        rgba(4, 9, 22, 0.62) 38%,
        rgba(4, 9, 22, 0.24) 72%,
        rgba(4, 9, 22, 0) 100%);
    z-index: 2;
}

/* ---------- brand: logo, hairline, title over tagline ---------- */

.gk-brand {
    --logo-h: clamp(1.35rem, 0.6rem + 2.5vmin, 3rem);
    display: flex;
    align-items: center;
    gap: clamp(0.75rem, 0.4rem + 1.4vmin, 1.5rem);
    min-width: 0;
    /* Leaves the other side of the top edge to the invitation at every width. */
    max-width: min(48vw, 46rem);
    pointer-events: all;
    animation: gk-brand-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.gk-actions button, .gk-actions label, .gk-menu-toggle {
    pointer-events: all;
}

.gk-mark {
    display: inline-flex;
    /* Held for the controls; the hold must not open the image callout or start a drag. */
    -webkit-touch-callout: none;
    flex: none;
    align-items: center;
    touch-action: manipulation;
    user-select: none;
    -webkit-user-select: none;
}

.gk-logo {
    display: block;
    height: var(--logo-h);
    width: auto;
    max-width: min(13rem, 26vw);
    object-fit: contain;
    object-position: left center;
    filter: drop-shadow(0 1px 10px rgba(4, 9, 22, 0.45));
    -webkit-user-drag: none;
}

/* A dark one-colour logo, painted white so it reads on the wall like the Meevo mark does. */
.gk-mark.is-white .gk-logo {
    filter: brightness(0) invert(1) drop-shadow(0 1px 10px rgba(4, 9, 22, 0.45));
}

.gk-brand-rule {
    flex: none;
    align-self: stretch;
    width: 1px;
    margin: 0.15em 0;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.42) 20%, rgba(255, 255, 255, 0.42) 80%, rgba(255, 255, 255, 0));
}

.gk-brand-text {
    display: grid;
    gap: clamp(0.15rem, 0.5vmin, 0.4rem);
    min-width: 0;
    text-shadow: 0 1px 14px rgba(4, 9, 22, 0.55);
}

.gk-title {
    margin: 0;
    touch-action: manipulation;
    font-size: clamp(1.15rem, 0.6rem + 2.3vmin, 2.4rem);
    font-weight: 700;
    line-height: 1.08;
    letter-spacing: -0.015em;
    color: var(--text);
    /* A long business name takes a second line rather than pushing into the invitation. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
    text-wrap: balance;
}

.gk-sub {
    margin: 0;
}

.gk-iq {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    font-size: clamp(0.82rem, 0.55rem + 1.15vmin, 1.35rem);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: 0.01em;
    color: rgba(244, 247, 255, 0.78);
    text-wrap: balance;
}

/* Upright, the brand is set larger: a tall kiosk is read from further back. It has the whole top
   edge unless the welcome route's invitation shares it (gallery-tryit.css). */
@media (orientation: portrait) {
    .gk-brand {
        --logo-h: clamp(1.5rem, 0.6rem + 3.4vmin, 4rem);
        max-width: 100%;
    }

    .gk-logo {
        max-width: min(18rem, 40vw);
    }

    .gk-title {
        font-size: clamp(1.3rem, 0.6rem + 3.2vmin, 3.2rem);
    }

    .gk-iq {
        font-size: clamp(0.9rem, 0.55rem + 1.6vmin, 1.75rem);
    }

    .gk-hint {
        max-width: calc(100% - 2rem);
        white-space: normal;
        text-align: center;
    }
}

/* A phone held upright: the logo over the words, so neither has to shrink to fit beside the other. */
@media (max-width: 34rem) {
    .gk-brand {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.55rem;
        max-width: 100%;
    }

    .gk-brand-rule {
        display: none;
    }

    .gk-logo {
        max-width: 50vw;
    }
}

@keyframes gk-brand-in {
    from { opacity: 0; transform: translateY(-0.5rem); }
    to { opacity: 1; transform: none; }
}

.gk-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    transition: opacity 0.32s ease, transform 0.32s ease;
}

.gk-menu-toggle {
    display: none;
}

@media (min-width: 48rem) {
    .gk-chrome {
        display: grid;
        grid-template-columns: max-content minmax(0, 1fr);
        align-items: start;
    }

    .gk-actions {
        min-width: 0;
        justify-content: flex-end;
    }
}

/* Sits in the same pill family as the buttons beside it, so the control bar reads as one row. */
.gk-slider {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    height: var(--pill-h);
    padding: 0 0.95rem;
    border: 1px solid var(--edge);
    border-radius: 999px;
    background: rgba(9, 20, 48, 0.55);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.04em;
    color: var(--text-dim);
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.gk-slider:hover {
    border-color: color-mix(in srgb, var(--accent) 50%, transparent);
    color: var(--text);
}

.gk-slider > span {
    line-height: 1;
}

.gk-slider input[type="range"] {
    appearance: none;
    -webkit-appearance: none;
    width: clamp(72px, 8vw, 104px);
    height: 100%;
    margin: 0;
    background: linear-gradient(rgba(244, 247, 255, 0.28), rgba(244, 247, 255, 0.28)) center / 100% 4px no-repeat;
    cursor: pointer;
}

.gk-slider input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    border: 0;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
}

.gk-slider input[type="range"]::-moz-range-thumb {
    width: 15px;
    height: 15px;
    border: 0;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
}

.gk-slider input[type="range"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
}

.gk-btn {
    appearance: none;
    /* Flex centring rather than symmetric padding: the type here has tall caps and no descenders,
       so padding alone leaves the label visibly high in the pill. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--pill-h);
    border: 1px solid var(--edge);
    border-radius: 999px;
    background: rgba(9, 20, 48, 0.55);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.04em;
    padding: 0 1.1rem;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.gk-btn:hover {
    background: color-mix(in srgb, var(--brand) 72%, transparent);
    border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.gk-btn:active {
    transform: translateY(1px);
}

.gk-btn.is-on {
    color: var(--text);
    background: var(--brand);
    border-color: var(--brand-hover);
}

.gk-btn.is-primary {
    color: var(--text);
    background: var(--brand);
    border-color: var(--brand-hover);
    font-weight: 700;
}

.gk-btn.is-primary:hover {
    background: var(--brand-hover);
    border-color: var(--accent);
}

.gk-btn:focus-visible,
.gk-menu-toggle:focus-visible,
.gk-spot-close:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.gk-hint {
    position: absolute;
    left: 50%;
    bottom: clamp(1rem, 2.5vw, 1.75rem);
    transform: translateX(-50%);
    margin: 0;
    padding: 0.45rem 1rem;
    border-radius: 999px;
    background: rgba(9, 20, 48, 0.5);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    white-space: nowrap;
    z-index: 2;
    transition: opacity 0.7s ease;
}

/* Withdrawn: the operator controls and the interaction hint leave together. The brand stays. */
.gk.is-chrome-away .gk-actions {
    opacity: 0;
    transform: translateY(-0.75rem);
    pointer-events: none;
}

.gk.is-chrome-away .gk-menu-toggle {
    opacity: 0;
    transform: translateY(-0.75rem);
    pointer-events: none;
}

.gk.is-chrome-away .gk-hint {
    opacity: 0;
    pointer-events: none;
}

/* ---------- spotlight chrome ---------- */

/*
  The compared images are drawn on the canvas so the open transition is one continuous motion.
  Only the close control and caption live here, fading in once the frame has settled.
*/
.gk-spot {
    position: absolute;
    inset: 0;
    z-index: 4;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.28s ease;
}

.gk-spot.is-open {
    opacity: 1;
    transition-delay: 0.3s;
}

.gk-spot.is-kiosk {
    position: absolute;
    inset: 0;
    z-index: 1000;
    visibility: hidden;
    overflow: hidden;
    background: var(--navy-deep);
    transform: scale(0.1);
    transform-origin: 50% 50%;
    box-shadow: 0 8px 40px rgba(4, 9, 22, 0.66);
    opacity: 0;
    pointer-events: auto;
    transition: opacity 0.26s ease, visibility 0s;
    will-change: transform;
}

.gk-spot.is-kiosk.is-mounted {
    visibility: visible;
    opacity: 1;
}

.gk-spot.is-kiosk:not(.is-mounted) {
    transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}

.gk-spot.is-kiosk > .gk-spot-close,
.gk-spot.is-kiosk > .gk-spot-caption,
.gk-spot.is-kiosk > .gk-spot-hint {
    display: none;
}

.gk-spot > look-lab-app {
    display: none;
    width: 100%;
    height: 100%;
}

.gk-spot > look-lab-app[hidden] {
    display: none !important;
}

.gk-spot.is-kiosk > look-lab-app:not([hidden]) {
    display: block;
}

.gk-spot-close {
    position: absolute;
    top: clamp(1rem, 2.4vw, 1.75rem);
    right: clamp(1rem, 2.4vw, 1.75rem);
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    border: 1px solid var(--edge);
    border-radius: 50%;
    background: rgba(9, 20, 48, 0.72);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    color: var(--text);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    pointer-events: auto;
    transition: background-color 0.18s ease, border-color 0.18s ease;
}

.gk-spot-close:hover {
    background: color-mix(in srgb, var(--brand) 78%, transparent);
    border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.gk-spot-caption,
.gk-spot-hint {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    max-width: min(72ch, 86vw);
    text-align: center;
}

.gk-spot-caption {
    bottom: clamp(3.1rem, 7vh, 4.4rem);
    font-size: clamp(1rem, 1.6vw, 1.3rem);
    font-weight: 600;
    text-wrap: balance;
}

.gk-spot-hint {
    bottom: clamp(1.4rem, 3.5vh, 2.2rem);
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    color: var(--text-dim);
}

/* Nothing to wipe between: the drag instruction would be a lie. */
.gk-spot:not(.has-compare) .gk-spot-hint {
    display: none;
}

/* ---------- curation ---------- */

/*
  Holding ctrl/cmd over the wall arms a hide. The cursor is the only feedback available before the
  pointer settles on a tile, so it carries the verb: a crossed-out eye to hide, a plus to restore.
*/
.gk.is-curate-hide .gk-canvas {
    cursor: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M15 4 A11 11 0 1 1 14.99 4Z' stroke='%23ff7a90' fill='rgba(12,20,44,0.86)'/%3E%3Cpath d='M9.5 9.5 L20.5 20.5' stroke='%23ff7a90'/%3E%3C/g%3E%3C/svg%3E") 15 15, crosshair;
}

.gk.is-curate-show .gk-canvas {
    cursor: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cg fill='none' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M15 4 A11 11 0 1 1 14.99 4Z' stroke='%2394a7ad' fill='rgba(12,20,44,0.86)'/%3E%3Cpath d='M15 9.5 L15 20.5 M9.5 15 L20.5 15' stroke='%2394a7ad'/%3E%3C/g%3E%3C/svg%3E") 15 15, crosshair;
}

/* Sits above the spotlight: a confirmation that could be covered would be worse than none. */
.gk-confirm {
    position: absolute;
    inset: 0;
    z-index: 6;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    background: rgba(4, 9, 22, 0.72);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    animation: gk-confirm-in 0.2s ease both;
}

.gk-confirm-card {
    width: min(30rem, 100%);
    padding: 1.6rem 1.7rem 1.4rem;
    border: 1px solid var(--edge);
    border-radius: 18px;
    background: rgba(9, 20, 48, 0.94);
    box-shadow: 0 26px 60px rgba(2, 6, 18, 0.6);
    text-align: center;
    animation: gk-card-in 0.24s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}

.gk-confirm-eyebrow {
    margin: 0;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
}

.gk-confirm-title {
    margin: 0.4rem 0 1.1rem;
    font-size: clamp(1.15rem, 2vw, 1.45rem);
    font-weight: 700;
    letter-spacing: -0.01em;
}

.gk-confirm-preview {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.7rem;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 14px;
    background: rgba(4, 10, 26, 0.6);
    text-align: left;
}

.gk-confirm-preview img {
    width: 64px;
    height: 64px;
    flex: none;
    border-radius: 10px;
    object-fit: cover;
    background: #11223f;
}

.gk-confirm-caption {
    margin: 0;
    font-size: 0.86rem;
    color: var(--text-dim);
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

.gk-confirm-body {
    margin: 1rem 0 1.3rem;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-dim);
    text-wrap: pretty;
}

.gk-confirm-actions {
    display: flex;
    justify-content: center;
    gap: 0.6rem;
}

@keyframes gk-confirm-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes gk-card-in {
    from { opacity: 0; transform: translateY(10px) scale(0.98); }
    to { opacity: 1; transform: none; }
}

/* ---------- status ---------- */

.gk-status {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
    max-width: 40ch;
    padding: 1rem 1.4rem;
    border: 1px solid var(--edge);
    border-radius: 14px;
    background: rgba(9, 20, 48, 0.82);
    text-align: center;
    color: var(--text-dim);
    z-index: 3;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.gk-status.is-on {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .gk-boot-mark {
        animation-duration: 2.4s;
    }

    .gk-brand {
        animation: none;
    }

    .gk-chrome,
    .gk-actions,
    .gk-menu-toggle,
    .gk-hint,
    .gk-spot,
    .gk-status {
        transition-duration: 0.01ms;
    }

    .gk-confirm,
    .gk-confirm-card {
        animation-duration: 0.01ms;
    }
}
