/* ==========================================================================
   Site showcase components (real website screenshots, used to sell builds)

     .sd  — hero "deck": a 3D fan of browser cards, click one to bring it
            forward, the front one pans down its own homepage.
     .cv  — "conveyor": rows of site tiles drifting past, speed and direction
            coupled to how you scroll the page. Click a tile to enlarge.
     .lb  — the shared lightbox both of them open (full-length screenshot,
            desktop/mobile, prev/next through every site on the page).

   Deliberately plain CSS rather than Tailwind utilities: these are heavily
   transform-driven and the values are computed in site-showcase.js, so they
   would be a mess of arbitrary-value classes and a tailwind.css rebuild on
   every tweak. Behaviour lives in public/assets/js/site-showcase.js.
   ========================================================================== */

:root {
    --ss-navy: #0f1b33;
    --ss-blue: #224685;
    --ss-line: #e2e8f0;
}

/* ============================ hero deck ============================ */

/* Clips the fan. The cards at the back of the arc are rotated in 3D, so
   perspective projects them WIDER than their own box and they used to push the
   document past the viewport on phones (53px of horizontal scroll). Clipping
   here rather than on .sd-stage keeps the vertical padding, so the front card's
   drop shadow is not sliced off at the same time. */
.sd { position: relative; width: 100%; }

/* Clips and fades the fan. The cards behind the front one are rotated in 3D,
   so perspective projects them wider than their own box: left unclipped they
   pushed the document past the viewport on phones (53px of horizontal scroll),
   and a big front card means they MUST run past the column edge anyway. So
   fade them out there rather than slicing them off square. The vertical
   padding keeps the front card's drop shadow out of the clip, and the caption
   below sits OUTSIDE this box so the mask never touches the text. */
.sd-frame {
    position: relative;
    overflow: hidden;
    padding-block: 2.25rem;
    margin-block: -2.25rem;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.sd-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9.8;
    perspective: 1800px;
    perspective-origin: 50% 45%;
    transform-style: preserve-3d;
    touch-action: pan-y;
}

.sd-card {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 70%;
    margin: 0;
    padding: 0;
    border: 0;
    background: #fff;
    border-radius: 12px;
    overflow: hidden;
    text-align: left;
    cursor: pointer;
    transform-origin: 50% 50%;
    box-shadow: 0 30px 60px -28px rgba(15, 27, 51, .55), 0 6px 18px -10px rgba(15, 27, 51, .3);
    transition: transform .75s cubic-bezier(.22, .8, .28, 1),
                opacity .55s ease,
                filter .55s ease,
                box-shadow .45s ease;
    will-change: transform;
    -webkit-tap-highlight-color: transparent;
}
.sd-card:focus-visible { outline: 3px solid #3b82f6; outline-offset: 3px; }
.sd.is-dragging .sd-card { transition: none; }

/* mini browser chrome */
.sd-chrome {
    display: flex;
    align-items: center;
    gap: .35rem;
    height: 30px;
    padding: 0 .7rem;
    background: #f1f5f9;
    border-bottom: 1px solid var(--ss-line);
}
.sd-chrome i { width: 9px; height: 9px; border-radius: 50%; background: #cbd5e1; flex: 0 0 auto; }
.sd-chrome i:nth-child(1) { background: #f87171; }
.sd-chrome i:nth-child(2) { background: #fbbf24; }
.sd-chrome i:nth-child(3) { background: #34d399; }
.sd-url {
    margin-left: .45rem;
    flex: 1;
    min-width: 0;
    height: 18px;
    background: #fff;
    border: 1px solid var(--ss-line);
    border-radius: 999px;
    display: flex;
    align-items: center;
    padding: 0 .6rem;
    font-size: .66rem;
    font-weight: 600;
    color: #64748b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sd-shot {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: #fff;
}
/* Top of the page only. The cards used to swap in a taller crop and pan down
   the homepage; Lee dropped that (2026-08-06): the deck rotates, the shot
   holds still. Anyone who wants the whole page clicks into the lightbox. */
.sd-shot img {
    position: absolute;
    inset: 0 0 auto 0;
    display: block;
    width: 100%;
    height: auto;
}

/* "Enlarge" hint on the front card */
.sd-open {
    position: absolute;
    left: 50%;
    bottom: .9rem;
    transform: translateX(-50%) translateY(6px);
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .45rem .95rem;
    border-radius: 999px;
    background: rgba(15, 27, 51, .86);
    backdrop-filter: blur(4px);
    color: #fff;
    font-size: .78rem;
    font-weight: 700;
    white-space: nowrap;
    opacity: 0;
    transition: opacity .3s ease, transform .3s ease;
    pointer-events: none;
}
.sd-card.is-front:hover .sd-open,
.sd-card.is-front:focus-visible .sd-open { opacity: 1; transform: translateX(-50%) translateY(0); }
.sd-open svg { width: .85rem; height: .85rem; }

/* caption + dots */
.sd-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.1rem;
    min-height: 2.6rem;
}
.sd-titles { min-width: 0; }
.sd-name {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ss-navy);
    line-height: 1.2;
    transition: opacity .25s ease;
}
.sd-sector { font-size: .8rem; font-weight: 600; color: #64748b; transition: opacity .25s ease; }
.sd-meta.is-swapping .sd-name, .sd-meta.is-swapping .sd-sector { opacity: 0; }

.sd-nav { display: flex; align-items: center; gap: .4rem; flex: 0 0 auto; }
.sd-nav button {
    width: 9px;
    height: 9px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: #cbd5e1;
    cursor: pointer;
    transition: background .3s ease, width .3s ease;
}
.sd-nav button.is-on { background: var(--ss-blue); width: 26px; }
.sd-nav button:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; }

@media (max-width: 1023px) {
    .sd-card { width: 78%; }
    .sd-stage { aspect-ratio: 16 / 11; }
    .sd-meta { flex-wrap: wrap; gap: .5rem 1rem; }
}

@media (prefers-reduced-motion: reduce) {
    .sd-card { transition: opacity .3s ease; }
}

/* ============================ conveyor ============================ */

.cv { position: relative; overflow: hidden; --cv-bg: #fff; }
.cv--slate { --cv-bg: #f8fafc; }
.cv--navy  { --cv-bg: #224685; }

/* The belts run wider than the section and are tilted, so their own ends are
   off-screen. These fades sit at the SECTION's edges instead, in the section's
   own colour, so tiles dissolve in and out rather than being chopped in half.
   Scoped to the belt wrapper so they never wash over the heading above. */
.cv-belt { position: relative; }
.cv-belt::before, .cv-belt::after {
    content: '';
    position: absolute;
    top: -1px; bottom: -1px;
    width: clamp(40px, 7%, 140px);
    z-index: 3;
    pointer-events: none;
}
.cv-belt::before { left: 0;  background: linear-gradient(90deg, var(--cv-bg) 15%, transparent); }
.cv-belt::after  { right: 0; background: linear-gradient(270deg, var(--cv-bg) 15%, transparent); }

.cv-rows {
    display: flex;
    flex-direction: column;
    gap: clamp(.7rem, 1.4vw, 1.25rem);
    width: 116%;
    margin-left: -8%;
    transform: rotate(-2deg);
}
.cv-row { display: flex; overflow: hidden; }
.cv-track {
    display: flex;
    gap: clamp(.7rem, 1.4vw, 1.25rem);
    flex: 0 0 auto;
    will-change: transform;
}

.cv-tile {
    position: relative;
    flex: 0 0 auto;
    width: clamp(196px, 21vw, 290px);
    margin: 0;
    padding: 0;
    border: 1px solid var(--ss-line);
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
    cursor: pointer;
    text-align: left;
    box-shadow: 0 12px 26px -18px rgba(15, 27, 51, .5);
    transition: transform .35s cubic-bezier(.22, .8, .28, 1), box-shadow .35s ease;
    -webkit-tap-highlight-color: transparent;
}
.cv-tile:hover, .cv-tile:focus-visible {
    transform: translateY(-6px) scale(1.045);
    box-shadow: 0 26px 48px -20px rgba(15, 27, 51, .55);
    z-index: 2;
}
.cv-tile:focus-visible { outline: 3px solid #3b82f6; outline-offset: 2px; }

.cv-chrome {
    display: flex;
    align-items: center;
    gap: .25rem;
    height: 22px;
    padding: 0 .5rem;
    background: #f1f5f9;
    border-bottom: 1px solid var(--ss-line);
}
.cv-chrome i { width: 6px; height: 6px; border-radius: 50%; background: #cbd5e1; flex: 0 0 auto; }
.cv-chrome i:nth-child(1) { background: #f87171; }
.cv-chrome i:nth-child(2) { background: #fbbf24; }
.cv-chrome i:nth-child(3) { background: #34d399; }
.cv-name {
    margin-left: .35rem;
    flex: 1;
    min-width: 0;
    font-size: .62rem;
    font-weight: 700;
    color: #64748b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cv-shot { position: relative; display: block; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; background: #f8fafc; }
.cv-shot img { display: block; width: 100%; height: auto; }

.cv-hover {
    position: absolute;
    inset: 22px 0 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    background: linear-gradient(180deg, rgba(15, 27, 51, .1), rgba(15, 27, 51, .72));
    color: #fff;
    font-size: .8rem;
    font-weight: 700;
    opacity: 0;
    transition: opacity .3s ease;
}
.cv-tile:hover .cv-hover, .cv-tile:focus-visible .cv-hover { opacity: 1; }
.cv-hover svg { width: .9rem; height: .9rem; }

.cv-hint {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    font-size: .85rem;
    font-weight: 600;
    color: #64748b;
}
.cv-hint svg { width: 1rem; height: 1rem; color: var(--ss-blue); }

/* tone: navy band */
.cv--navy .cv-tile { border-color: rgba(255, 255, 255, .14); }
.cv--navy .cv-hint { color: rgba(255, 255, 255, .75); }
.cv--navy .cv-hint svg { color: #93c5fd; }

@media (max-width: 767px) {
    .cv-rows { width: 132%; margin-left: -16%; }
    .cv-tile { width: 172px; }
}

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

/* ============================ lightbox ============================ */

.lb {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(.6rem, 2vw, 1.75rem);
    opacity: 0;
    transition: opacity .28s ease;
}
.lb[hidden] { display: none; }
.lb.is-open { opacity: 1; }
.lb-back { position: absolute; inset: 0; background: rgba(9, 16, 31, .82); backdrop-filter: blur(6px); }

.lb-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(1180px, 100%);
    /* height, not max-height: the body's only children are absolutely
       positioned, so it contributes no content height and a content-sized
       panel collapses to just the header and footer. */
    height: 100%;
    background: #fff;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .7);
    transform: translateY(14px) scale(.985);
    transition: transform .35s cubic-bezier(.22, .8, .28, 1);
}
.lb.is-open .lb-panel { transform: none; }

.lb-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .85rem 1rem .85rem 1.25rem;
    border-bottom: 1px solid var(--ss-line);
    flex: 0 0 auto;
}
.lb-titles { min-width: 0; flex: 1; }
.lb-title { font-size: 1.05rem; font-weight: 700; color: var(--ss-navy); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-sector { font-size: .78rem; font-weight: 600; color: #64748b; }

.lb-toggle { display: inline-flex; background: #eef2f8; border-radius: 999px; padding: .18rem; gap: .15rem; flex: 0 0 auto; }
.lb-toggle button {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    border: 0;
    cursor: pointer;
    background: transparent;
    color: #51618a;
    font-size: .8rem;
    font-weight: 700;
    padding: .4rem .85rem;
    border-radius: 999px;
    transition: background .2s, color .2s;
}
.lb-toggle button svg { width: .95rem; height: .95rem; }
.lb-toggle button.is-on { background: #fff; color: var(--ss-blue); box-shadow: 0 1px 3px rgba(15, 27, 51, .12); }

.lb-close, .lb-step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border: 1px solid var(--ss-line);
    border-radius: 999px;
    background: #fff;
    color: #475569;
    cursor: pointer;
    flex: 0 0 auto;
    transition: background .2s, color .2s, border-color .2s;
}
.lb-close:hover, .lb-step:hover { background: #f1f5f9; color: var(--ss-navy); }
.lb-close svg, .lb-step svg { width: 1.1rem; height: 1.1rem; }

/* The frames are absolutely positioned rather than flex children on purpose.
   As a flex item with height:100% the desktop frame resolved to its CONTENT
   height (2811px for a full-page screenshot) instead of the body height, so
   .lb-scroll was never shorter than its image and would not scroll at all on
   desktop, while the mobile phone frame happened to work. Against a
   definite-height relative parent, inset gives a definite height every time. */
.lb-body {
    position: relative;
    flex: 1;
    min-height: 0;
    background: #eef2f8;
    overflow: hidden;
    --lb-pad: clamp(.75rem, 2vw, 1.4rem);
}

.lb-frame { display: none; position: absolute; inset: var(--lb-pad); }
.lb[data-device="desktop"] .lb-frame--desktop { display: flex; flex-direction: column; }
.lb[data-device="mobile"]  .lb-frame--mobile  { display: flex; justify-content: center; }

.lb-window {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    background: #fff;
    border: 1px solid var(--ss-line);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 20px 40px -24px rgba(15, 27, 51, .5);
}
.lb-bar { display: flex; align-items: center; gap: .35rem; height: 34px; flex: 0 0 34px; padding: 0 .8rem; background: #f1f5f9; border-bottom: 1px solid var(--ss-line); }
.lb-bar i { width: 10px; height: 10px; border-radius: 50%; background: #cbd5e1; }
.lb-bar i:nth-child(1) { background: #f87171; }
.lb-bar i:nth-child(2) { background: #fbbf24; }
.lb-bar i:nth-child(3) { background: #34d399; }
.lb-bar span { margin-left: .5rem; font-size: .72rem; font-weight: 600; color: #64748b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.lb-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scroll-behavior: smooth; background: #fff; }
.lb-scroll img { display: block; width: 100%; height: auto; }

.lb-phone {
    position: relative;
    height: 100%;
    aspect-ratio: 1000 / 2060;
    margin: 0 auto;
    background: var(--ss-navy);
    border-radius: 30px;
    padding: 9px;
    display: flex;
    box-shadow: 0 24px 50px -26px rgba(15, 27, 51, .6);
}
.lb-phone .lb-scroll { border-radius: 22px; }
.lb-notch { position: absolute; top: 11px; left: 50%; transform: translateX(-50%); width: 34%; height: 15px; background: var(--ss-navy); border-radius: 0 0 12px 12px; z-index: 2; }

.lb-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .8rem 1.25rem;
    border-top: 1px solid var(--ss-line);
    flex: 0 0 auto;
    flex-wrap: wrap;
}
.lb-steps { display: flex; align-items: center; gap: .5rem; }
.lb-count { font-size: .8rem; font-weight: 600; color: #64748b; font-variant-numeric: tabular-nums; }
.lb-cta {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    background: var(--ss-blue);
    color: #fff;
    font-weight: 700;
    font-size: .9rem;
    padding: .65rem 1.3rem;
    border-radius: 999px;
    transition: background .2s, transform .2s;
}
.lb-cta:hover { background: #1a3568; transform: translateY(-1px); }
.lb-cta svg { width: 1rem; height: 1rem; }
.lb-scrollhint { font-size: .8rem; color: #64748b; display: inline-flex; align-items: center; gap: .4rem; }
.lb-scrollhint svg { width: .95rem; height: .95rem; color: var(--ss-blue); }

@media (max-width: 767px) {
    .lb-head { padding: .7rem .75rem; gap: .6rem; }
    .lb-sector, .lb-scrollhint { display: none; }
    .lb-toggle button span { display: none; }
    .lb-toggle button { padding: .45rem .7rem; }
    .lb-foot { padding: .7rem .75rem; }
}
