/* ==========================================================================
   NX PAGES — inner-page layer
   Everything the sub-pages need on top of css/nx.css: page heroes, card
   grids, process steps, galleries, video walls, the before/after widget and
   the legal document. Same tokens, same rhythm, same motion as index.html.
   Load order is always: nx.css → nx-pages.css.
   ========================================================================== */

/* Sub-pages carry no wordmark in the hero, so the header mark is on from the
   first frame instead of fading in past the fold like it does on index. */
.nx-page .nx-head__mark { opacity: 1; transform: none; }

/* ── Page hero ──────────────────────────────────────────────────────────────
   The index hero is carried by the DEZIGNITE wordmark and its fluid canvas.
   Sub-pages get the same edge-to-edge feel from a display title instead, so
   the type scale can adapt to words of any length. */
.nx-phero {
    position: relative;
    min-height: 82svh;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: clamp(50px, 9vw, 110px);
    padding: calc(var(--nx-bar) * 1.35) 0 24px;
    overflow: hidden;
}

.nx-phero__top { padding-inline: var(--nx-gutter); }

.nx-phero__slug {
    display: block;
    margin-bottom: clamp(22px, 3vw, 34px);
}

/* Display title — one notch under the index wordmark so a two-word page
   title still bleeds toward both gutters without towering off-screen. */
.nx-phero__title {
    font-size: clamp(3rem, 12vw, 10.5rem);
    font-weight: 700;
    line-height: .84;
    letter-spacing: -.055em;
    text-transform: uppercase;
}
/* .nx-lines ends its last mask with a -.16em margin, cancelling the padding
   that keeps descenders out of the clip. Harmless at body sizes; at 10.5rem it
   is 27px, and it comes straight out of the gap before the lede — which is why
   the lede otherwise sits on the title's baseline. Give it back in the title's
   own em so the two always cancel, whatever the clamp resolves to. */
.nx-phero__title.nx-lines { margin-bottom: .16em; }

.nx-phero__title .dim { color: var(--nx-mute); }
.nx-dark .nx-phero__title .dim,
.nx-phero--dark .nx-phero__title .dim { color: var(--nx-mute-dark); }

/* Slightly tighter for the long single words (/graphics, /development) */
.nx-phero__title--long { font-size: clamp(2.3rem, 9.4vw, 8rem); }

/* Legal documents: a long sentence-case title, and no full-height hero —
   the reader wants the text, not a landing moment. */
.nx-phero--doc {
    min-height: 0;
    gap: clamp(28px, 4vw, 52px);
    padding-bottom: 0;
}
.nx-phero__title--doc {
    font-size: clamp(1.9rem, 5.4vw, 4.4rem);
    line-height: 1;
    letter-spacing: -.04em;
    text-transform: none;
    max-width: 18ch;
}

.nx-phero__lede {
    margin-top: clamp(26px, 3.4vw, 42px);
    max-width: 44ch;
    font-size: clamp(1rem, 1.5vw, 1.3rem);
    font-weight: 400;
    line-height: 1.35;
    letter-spacing: -.02em;
}

.nx-phero__foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px;
    padding-inline: var(--nx-gutter);
    font-size: 13px;
    letter-spacing: -.01em;
}

.nx-phero--dark { background: var(--nx-ink); color: var(--nx-white); }

@media (max-width: 760px) {
    .nx-phero { min-height: 74svh; }
    .nx-phero__foot { flex-direction: column; align-items: flex-start; gap: 16px; }
}

/* The hero footer's meta row reuses the index's social strip */
.nx-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
}
.nx-meta .sep { color: var(--nx-mute); }
.nx-dark .nx-meta .sep,
.nx-phero--dark .nx-meta .sep { color: var(--nx-mute-dark); }
.nx-meta a { transition: opacity .3s ease; }
.nx-meta a:hover { opacity: .5; }

/* Language toggle on a dark ground — nx.css paints the light-hero variant */
.nx-dark .nx-langwrap .lang-opt,
.nx-phero--dark .nx-langwrap .lang-opt { color: var(--nx-mute-dark); }
.nx-dark .nx-langwrap .lang-opt:hover,
.nx-dark .nx-langwrap .lang-opt.active,
.nx-phero--dark .nx-langwrap .lang-opt:hover,
.nx-phero--dark .nx-langwrap .lang-opt.active { color: var(--nx-white); }
.nx-dark .nx-langwrap .lang-sep,
.nx-phero--dark .nx-langwrap .lang-sep { color: var(--nx-line-dark); }

/* ── Back link ──────────────────────────────────────────────────────────── */
.nx-back {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--nx-mute);
    transition: color .3s ease;
}
.nx-dark .nx-back,
.nx-phero--dark .nx-back { color: var(--nx-mute-dark); }
.nx-back:hover { color: currentColor; opacity: 1; }
.nx .nx-dark .nx-back:hover,
.nx .nx-phero--dark .nx-back:hover { color: var(--nx-white); }
.nx-back svg { transition: transform .45s var(--nx-ease); }
.nx-back:hover svg { transform: translateX(-4px); }

/* ── Section head: a mono label with a hairline running off to the edge ── */
.nx-head-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 20px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-head-row { border-bottom-color: var(--nx-line-dark); }
.nx-head-row__note {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-head-row__note { color: var(--nx-mute-dark); }

/* Standard block lede under a section headline */
.nx-lede {
    margin-top: clamp(20px, 2.6vw, 30px);
    max-width: 58ch;
    font-size: clamp(.98rem, 1.25vw, 1.1rem);
    line-height: 1.55;
    color: var(--nx-mute);
}
.nx-dark .nx-lede { color: var(--nx-mute-dark); }

/* ── Card grid ──────────────────────────────────────────────────────────── */
.nx-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    margin-top: clamp(34px, 5vw, 56px);
    border-top: 1px solid var(--nx-line);
}
.nx-dark .nx-grid { border-top-color: var(--nx-line-dark); }

@media (min-width: 720px)  { .nx-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .nx-grid--3 { grid-template-columns: repeat(3, 1fr); } }

.nx-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: clamp(26px, 3vw, 40px) clamp(20px, 2.4vw, 34px) clamp(30px, 3.6vw, 46px) 0;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-card { border-bottom-color: var(--nx-line-dark); }

/* Vertical rules between columns, never on the first of a row */
@media (min-width: 720px) {
    .nx-card { padding-left: clamp(20px, 2.4vw, 34px); }
    .nx-grid > .nx-card:nth-child(2n+1) { padding-left: 0; }
    .nx-grid > .nx-card:nth-child(2n)   { border-left: 1px solid var(--nx-line); }
    .nx-dark .nx-grid > .nx-card:nth-child(2n) { border-left-color: var(--nx-line-dark); }
}
@media (min-width: 1080px) {
    .nx-grid--3 > .nx-card:nth-child(2n+1) { padding-left: clamp(20px, 2.4vw, 34px); }
    .nx-grid--3 > .nx-card:nth-child(2n)   { border-left: 1px solid var(--nx-line); }
    .nx-grid--3 > .nx-card:nth-child(3n+1) { padding-left: 0; border-left: 0; }
    .nx-grid--3 > .nx-card:nth-child(3n+2),
    .nx-grid--3 > .nx-card:nth-child(3n)   { border-left: 1px solid var(--nx-line); }
    .nx-dark .nx-grid--3 > .nx-card { border-left-color: var(--nx-line-dark); }
}

.nx-card__idx {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .1em;
    color: var(--nx-mute);
}
.nx-dark .nx-card__idx { color: var(--nx-mute-dark); }

.nx-card__icon {
    width: 24px;
    height: 24px;
    color: currentColor;
    opacity: .55;
}

.nx-card__title {
    font-size: clamp(1.15rem, 1.7vw, 1.5rem);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -.03em;
}

.nx-card__desc {
    font-size: .96rem;
    line-height: 1.55;
    color: var(--nx-mute);
    max-width: 46ch;
}
.nx-dark .nx-card__desc { color: var(--nx-mute-dark); }

.nx-card__go {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-top: auto;
    padding-top: 12px;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--nx-mute);
    transition: color .35s ease;
}
.nx-dark .nx-card__go { color: var(--nx-mute-dark); }
.nx-card__go:hover { color: inherit; }
.nx .nx-dark .nx-card__go:hover { color: var(--nx-white); }
.nx-card__go svg { transition: transform .45s var(--nx-ease); }
.nx-card__go:hover svg { transform: translateX(5px); }

/* ── Process steps ──────────────────────────────────────────────────────── */
.nx-steps {
    list-style: none;
    margin: clamp(34px, 5vw, 56px) 0 0;
    padding: 0;
    border-top: 1px solid var(--nx-line);
}
.nx-dark .nx-steps { border-top-color: var(--nx-line-dark); }

.nx-step {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    padding: clamp(24px, 2.8vw, 36px) 0;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-step { border-bottom-color: var(--nx-line-dark); }

@media (min-width: 800px) {
    .nx-step { grid-template-columns: 5rem minmax(0, 15rem) minmax(0, 1fr); gap: 30px; align-items: baseline; }
}

.nx-step__n {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    color: var(--nx-mute);
}
.nx-dark .nx-step__n { color: var(--nx-mute-dark); }

.nx-step__t {
    font-size: clamp(1.1rem, 1.7vw, 1.45rem);
    font-weight: 500;
    letter-spacing: -.03em;
    line-height: 1.12;
}

.nx-step__d {
    font-size: .96rem;
    line-height: 1.55;
    color: var(--nx-mute);
    max-width: 56ch;
}
.nx-dark .nx-step__d { color: var(--nx-mute-dark); }


/* ── Tiles / gallery ────────────────────────────────────────────────────── */
.nx-gallery {
    display: grid;
    gap: clamp(14px, 1.6vw, 22px);
    margin-top: clamp(30px, 4vw, 48px);
    grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 820px) { .nx-gallery { grid-template-columns: repeat(3, 1fr); } }

.nx-gallery--2 { grid-template-columns: 1fr; }
@media (min-width: 700px) { .nx-gallery--2 { grid-template-columns: repeat(2, 1fr); } }

.nx-gallery--wide { grid-template-columns: 1fr; }
@media (min-width: 820px) { .nx-gallery--wide { grid-template-columns: repeat(2, 1fr); } }

.nx-gallery--sq { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px) { .nx-gallery--sq { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1080px) { .nx-gallery--sq { grid-template-columns: repeat(6, 1fr); } }

.nx-tile { display: block; }

.nx-tile__media {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: #141414;
    aspect-ratio: 16 / 9;
}
/* Sizing and motion come from .nx-par on the frame: the image is taller than
   its box and drifts as it crosses the viewport, which replaces the old
   hover zoom. */

.nx-tile--sq .nx-tile__media  { aspect-ratio: 1 / 1; }
.nx-tile--wide .nx-tile__media { aspect-ratio: 16 / 9; }
.nx-tile--tall .nx-tile__media { aspect-ratio: 4 / 5; }

/* Artwork frame — for portfolio pieces rather than photography.
   A cropped design is a different design, so these carry no forced ratio and
   no parallax: the file's own proportions set the height and the whole piece
   is on show. Photography keeps the drift; work does not. */
/* Portrait-ish photography — 16/9 threw away a third of a square source. */
.nx-tile__media--photo { aspect-ratio: 4 / 3; }

.nx-tile__media--art { aspect-ratio: auto; }
.nx .nx-tile__media--art > img {
    position: static;
    width: 100%;
    height: auto;
    transform: none;
}

.nx-tile__cap {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-tile__cap { color: var(--nx-mute-dark); }
.nx-tile__cap b { font-weight: 400; color: inherit; }

.nx-tile__name {
    display: block;
    margin-top: 12px;
    font-size: 1.02rem;
    font-weight: 500;
    letter-spacing: -.025em;
}
.nx-tile__note {
    display: block;
    margin-top: 6px;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--nx-mute);
    max-width: 40ch;
}
.nx-dark .nx-tile__note { color: var(--nx-mute-dark); }

/* ── Horizontal rail gallery ────────────────────────────────────────────────
   A scattered canvas that reads sideways. Two modes, same markup:

   • base — the viewport is a native overflow-x strip. Touch swipes it, a
     trackpad swipes it, nothing needs JavaScript. This is what phones get and
     what everyone gets if js/nx.js never lands.
   • .is-pinned — js/nx.js measures the track, stretches .nx-rail to the
     travel distance and sticks the viewport to the top of the screen, then
     drives .nx-rail__track with a transform as the page scrolls. Added only
     on a wide fine-pointer screen with motion allowed.

   Plates are sized in --nx-u, not vw. A wide short screen would otherwise get
   plates too tall for their vertical offsets, which are in svh: capping the
   unit against 1.85svh keeps a plate's height roughly constant in svh no
   matter how letterboxed the viewport is. */
.nx-rail {
    --nx-u: min(1vw, 1.85svh);
    --rail-gap: calc(5 * var(--nx-u));
    position: relative;
    background: var(--nx-paper);
    color: var(--nx-black);
}

/* The spacer. --rail-run is how far the canvas has to travel expressed as
   scroll distance; js/nx.js measures it and writes it here, and one screen on
   top of it is the length the pinned viewport holds. Both ends are stated in
   the same svh the viewport itself is sized in, so a phone hiding its address
   bar cannot leave the pin running past the end of the canvas. */
.nx-rail.is-pinned {
    height: calc(100svh + var(--rail-run, 0px));
}

/* The viewport positions; the pane inside it scrolls. Keeping those two jobs
   apart is what lets the HUD and the backdrop stay put: an absolutely
   positioned child of a scroll container travels with its content, so a HUD
   parked in the scroller would slide off the side of the strip. */
.nx-rail__vp {
    position: relative;
    height: 100svh;
    overflow: hidden;
}
.nx-rail.is-pinned .nx-rail__vp {
    position: sticky;
    top: 0;
}

.nx-rail__scroll {
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    /* On a desktop that never got the pinned mode the scrollbar is the only
       sign the strip moves at all. */
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, .25) transparent;
}

.nx-rail.is-pinned .nx-rail__scroll {
    overflow: hidden;
    scrollbar-width: none;
}
.nx-rail.is-pinned .nx-rail__scroll::-webkit-scrollbar { display: none; }

/* Contour backdrop. Wider than the screen and parallaxed at a fraction of the
   track's speed, so the canvas has depth without another image to download. */
.nx-rail__bg {
    position: absolute;
    inset: 0;
    width: 190%;
    pointer-events: none;
    will-change: transform;
}
.nx-rail__bg svg { width: 100%; height: 100%; }
.nx-rail__bg path {
    stroke: rgba(0, 0, 0, .16);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}
.lowfx .nx-rail__bg { display: none; }

.nx-rail__track {
    position: relative;
    display: flex;
    align-items: flex-start;
    height: 100%;
    width: max-content;
    gap: var(--rail-gap);
    padding: calc(var(--nx-bar) + 26px) max(var(--nx-gutter), 6vw) 0;
}
.nx-rail.is-pinned .nx-rail__track { will-change: transform; }

/* ── Slots ── */
.nx-rail__slot {
    flex: 0 0 auto;
    scroll-snap-align: center;
    display: flex;
    flex-direction: column;
}

.nx-rail__slot--intro {
    width: min(78vw, 560px);
    align-self: stretch;
    justify-content: center;
    padding-bottom: 12svh;   /* clears the HUD */
}

.nx-rail__title {
    margin-top: 20px;
    font-size: clamp(2.1rem, 3.6vw, 3.6rem);
    font-weight: 500;
    line-height: 1.02;
    letter-spacing: -.035em;
}
.nx-rail__title .dim { color: var(--nx-mute); }

.nx-rail__lede {
    margin-top: 22px;
    max-width: 40ch;
    font-size: 1rem;
    line-height: 1.55;
    color: var(--nx-mute);
}

.nx-rail__cue {
    margin-top: 30px;
    color: var(--nx-mute);
}
.nx-rail__cue svg { animation: nx-rail-cue 2.4s var(--nx-ease-io) infinite; }
@keyframes nx-rail-cue {
    0%, 100% { transform: translateX(0); }
    50%      { transform: translateX(10px); }
}
.lowfx .nx-rail__cue svg { animation: none; }

/* Chapter marker — the category card that opens each run of plates. */
.nx-rail__slot--chapter {
    width: calc(22 * var(--nx-u));
    min-width: 190px;
    margin-top: calc(var(--y) * 1svh);
    gap: 10px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--nx-line);
}
.nx-chap__n {
    font-family: var(--nx-mono);
    font-size: clamp(1.6rem, 2.4vw, 2.3rem);
    letter-spacing: -.03em;
    color: var(--nx-black);
}
.nx-chap__name {
    font-size: clamp(1rem, 1.35vw, 1.25rem);
    font-weight: 500;
    letter-spacing: -.025em;
    line-height: 1.15;
}
.nx-chap__ratio {
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
}

/* ── Plates ── */
/* Doubled class: a plate is a <figure>, and the `.nx figure { margin: 0 }`
   reset in nx.css would otherwise out-specify the offsets that scatter it.

   The scatter is authored in the markup, four numbers per plate: --w and --y
   place it, --ml tucks it against its neighbour, --z decides which of an
   overlapping pair sits in front. Three more (--d, --t, --zs) are never read
   here; js/nx.js turns them into the drift, tilt and zoom each plate performs
   while it crosses the screen. */
.nx .nx-plate {
    position: relative;
    z-index: var(--z, 1);
    flex: 0 0 auto;
    scroll-snap-align: center;
    width: calc(var(--w) * var(--nx-u));
    min-width: 150px;
    margin-top: calc(var(--y) * 1svh);
    margin-left: calc(var(--ml, 0) * var(--nx-u));
    /* js/nx.js writes transform and opacity here every frame the plate is on
       screen — no transition, or the two would fight over every value. No
       will-change either: it would promote all twenty-eight for the sake of the
       five that are actually moving. */
}

.nx-plate__cap {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 11px;
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
    /* Plates tuck behind one another, so a caption can end up with a corner of
       the neighbour's photograph under it. The halo is the paper colour: it
       does nothing on the paper and lifts the type off anything darker. */
    text-shadow: 0 0 7px var(--nx-paper), 0 0 3px var(--nx-paper);
    transition: color .5s var(--nx-ease);
}
.nx-plate__cap b { font-weight: 400; color: rgba(0, 0, 0, .32); }

/* --ar is the source file's own ratio, so the box is cut to the artwork rather
   than the artwork to the box. object-fit: cover then has nothing to crop. */
.nx-plate__media {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: #e6e6e2;
    aspect-ratio: var(--ar, 1.778);
}

/* Avatars are circles on a square canvas — the file is cropped to the circle's
   bounding box, so clipping the box to a circle removes the last of the corner
   and leaves the artwork whole. */
.nx-plate--round .nx-plate__media {
    border-radius: 50%;
    background: none;
}

.nx .nx-plate__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Hover cannot touch transform — the crossing zoom owns it — so it lifts the
   plate off the paper instead. */
.nx-plate__media {
    transition: box-shadow .6s var(--nx-ease);
}
@media (hover: hover) and (pointer: fine) {
    .nx-plate:hover .nx-plate__cap { color: var(--nx-black); }
    .nx-plate:hover .nx-plate__media { box-shadow: 0 18px 50px rgba(0, 0, 0, .17); }
    .nx-plate--round:hover .nx-plate__media { box-shadow: 0 14px 40px rgba(0, 0, 0, .2); }
}

/* ── Closing panel ── */
.nx-rail__slot--outro {
    width: min(84vw, 620px);
    align-self: stretch;
    justify-content: center;
    padding-bottom: 12svh;
    margin-left: calc(6 * var(--nx-u));
}

.nx-rail__quote {
    font-size: clamp(1.5rem, 2.6vw, 2.5rem);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -.03em;
}
.nx-rail__quote .dim { color: var(--nx-mute); }

.nx-rail__sign {
    margin-top: 26px;
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-rail__act { margin-top: 30px; }

/* ── HUD ── */
.nx-rail__hud {
    position: absolute;
    left: max(var(--nx-gutter), 6vw);
    bottom: clamp(22px, 4svh, 44px);
    display: flex;
    align-items: center;
    gap: 16px;
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
    pointer-events: none;
}
.nx-rail__idx {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
}
.nx-rail__idx b {
    min-width: 34px;
    padding: 7px 9px 6px;
    border: 1px solid var(--nx-line);
    border-radius: 4px;
    font-weight: 400;
    text-align: center;
    color: var(--nx-black);
    font-variant-numeric: tabular-nums;
}
.nx-rail__bar {
    display: block;
    width: clamp(90px, 14vw, 210px);
    height: 1px;
    background: var(--nx-line);
}
.nx-rail__bar i {
    display: block;
    height: 100%;
    background: var(--nx-black);
    transform: scaleX(var(--rail-p, 0));
    transform-origin: 0 50%;
}
.nx-rail__hint { display: none; }
@media (min-width: 900px) { .nx-rail__hint { display: inline; } }

/* ── Phones ──────────────────────────────────────────────────────────────
   A phone gets the pinned canvas too. The run is driven by the page's own
   scroll, and a thumb does that as well as a wheel does — so the gallery
   fills the screen, travels sideways for its whole length and lets go, the
   same as it does on a desktop. Only the scale changes down here: a bigger
   unit so the plates read at arm's length, a shorter scatter so the whole
   spread still lands inside one screen under a header that never leaves.

   The flat strip below is what is left for the readers who never get the
   pin — reduced motion, a demoted page, or no script at all. */
@media (max-width: 899px) {
    .nx-rail.is-pinned { --nx-u: min(3vw, 1.9svh); }
    .nx-rail.is-pinned .nx-rail__track {
        padding: calc(var(--nx-bar) + 14px) var(--nx-gutter) 0;
        gap: calc(4 * var(--nx-u));
    }
    /* The widest plate on the canvas is wider than a phone. Capped, so one
       picture passing never becomes a page of its own; and the floor is
       lower than the desktop's, or the small plates would all collapse onto
       the same width and the scatter would flatten out. */
    .nx-rail.is-pinned .nx-plate {
        width: min(84vw, calc(var(--w) * var(--nx-u)));
        min-width: 108px;
        margin-top: calc(var(--y) * .92svh);
    }
    .nx-rail.is-pinned .nx-rail__slot--chapter {
        min-width: 150px;
        margin-top: calc(var(--y) * .92svh);
    }
    /* The backdrop drifts by a fraction of one screen, and one screen here is
       narrow — it has to be wider than the desktop's to cover the same run. */
    .nx-rail.is-pinned .nx-rail__bg { width: 260%; }

    /* Native-scroll mode: the strip has to breathe on its own page, and the
       wild vertical offsets belong to a full-height canvas, not to a band in
       the flow. Halve them and let the strip stand where it is. */
    .nx-rail:not(.is-pinned) { --nx-u: min(2.9vw, 2svh); }
    .nx-rail:not(.is-pinned) .nx-rail__vp { height: auto; }
    .nx-rail:not(.is-pinned) .nx-rail__scroll {
        padding-block: clamp(60px, 11vw, 110px);
        scroll-snap-type: x mandatory;
    }
    .nx-rail:not(.is-pinned) .nx-rail__track {
        height: auto;
        align-items: center;
        padding: 0 var(--nx-gutter) 56px;
        gap: clamp(26px, 7vw, 48px);
    }
    .nx-rail:not(.is-pinned) .nx-rail__slot--intro,
    .nx-rail:not(.is-pinned) .nx-rail__slot--outro {
        width: 82vw;
        align-self: center;
        padding-bottom: 0;
        margin-left: 0;
    }
    .nx-rail:not(.is-pinned) .nx-rail__slot--chapter { margin-top: 0; }
    .nx-rail:not(.is-pinned) .nx-plate {
        width: min(78vw, calc(var(--w) * var(--nx-u)));
        margin-top: calc(var(--y) * .18svh);
        margin-left: 0;
    }
    .nx-rail:not(.is-pinned) .nx-rail__bg { display: none; }

    .nx-rail__hud {
        left: var(--nx-gutter);
        bottom: clamp(18px, 5vw, 30px);
    }
}

/* ── Video wall ─────────────────────────────────────────────────────────── */
.nx-vids {
    display: grid;
    gap: clamp(16px, 2vw, 26px);
    margin-top: clamp(26px, 3.4vw, 40px);
    grid-template-columns: 1fr;
}
@media (min-width: 760px) { .nx-vids { grid-template-columns: repeat(2, 1fr); } }

.nx-vids--portrait { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px)  { .nx-vids--portrait { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1080px) { .nx-vids--portrait { grid-template-columns: repeat(5, 1fr); } }

.nx-vid__frame {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: #101010;
    aspect-ratio: 16 / 9;
}
.nx-vid--portrait .nx-vid__frame { aspect-ratio: 9 / 16; }

.nx-vid__frame video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #101010;
}

.nx-vid__play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border: 0;
    background: rgba(0, 0, 0, .28);
    cursor: pointer;
    color: var(--nx-white);
    transition: opacity .4s var(--nx-ease), background .4s var(--nx-ease);
}
.nx-vid__play span {
    display: grid;
    place-items: center;
    width: 58px;
    height: 58px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .92);
    color: #000;
    transition: transform .45s var(--nx-ease);
}
.nx-vid__play:hover span { transform: scale(1.08); }
.nx-vid.is-playing .nx-vid__play { opacity: 0; pointer-events: none; }

.nx-vid__meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
}
.nx-vid__title { font-size: .98rem; font-weight: 500; letter-spacing: -.02em; }
.nx-vid__type {
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
    white-space: nowrap;
}
.nx-dark .nx-vid__type { color: var(--nx-mute-dark); }
/* Portrait columns are too narrow to sit title and type on one line */
.nx-vid--portrait .nx-vid__type { display: block; margin-top: 5px; white-space: normal; }

/* Category head above a wall */
.nx-cat {
    display: flex;
    align-items: baseline;
    gap: 16px;
    margin-top: clamp(46px, 6vw, 76px);
    padding-bottom: 14px;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-cat { border-bottom-color: var(--nx-line-dark); }
.nx-cat__n,
.nx-cat__ratio {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-cat__n,
.nx-dark .nx-cat__ratio { color: var(--nx-mute-dark); }
.nx-cat__ratio { margin-left: auto; }
.nx-cat__name {
    font-size: clamp(1.15rem, 2vw, 1.7rem);
    font-weight: 500;
    letter-spacing: -.03em;
}

/* ── Tags ───────────────────────────────────────────────────────────────── */
.nx-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
}
.nx-tag {
    padding: 7px 13px;
    border: 1px solid var(--nx-line);
    border-radius: 999px;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-tag { border-color: var(--nx-line-dark); color: var(--nx-mute-dark); }

/* ── Team ───────────────────────────────────────────────────────────────── */
.nx-team {
    display: grid;
    gap: clamp(56px, 8vw, 120px);
    margin-top: clamp(44px, 6vw, 80px);
    grid-template-columns: 1fr;
}
.nx-member {
    display: grid;
    gap: clamp(22px, 3vw, 34px);
}
.nx-member__photo {
    position: relative;
    max-width: 430px;
    overflow: hidden;
    border-radius: 8px;
    aspect-ratio: 4 / 5;
    background: #161616;
}
/* Sizing and motion come from .nx-par on the photo frame */
.nx-member__idx {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 2;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .12em;
    color: rgba(255, 255, 255, .8);
}
/* Bio measure, not column width, sets the line length */
.nx-member__body { max-width: 46ch; }
.nx-member__name {
    font-size: clamp(1.15rem, 1.7vw, 1.4rem);
    font-weight: 500;
    letter-spacing: -.03em;
}
.nx-member__role {
    margin-top: 8px;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-member__role { color: var(--nx-mute-dark); }
.nx-member__bio {
    margin-top: 14px;
    font-size: .94rem;
    line-height: 1.55;
    color: var(--nx-mute);
}
.nx-dark .nx-member__bio { color: var(--nx-mute-dark); }

/* From tablet up the row splits in two and every second member mirrors it, so
   the portraits walk down the page left, right, left instead of standing in a
   row — three people read as three introductions rather than a cast list. */
@media (min-width: 860px) {
    .nx-member {
        grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
        align-items: center;
        gap: clamp(42px, 7vw, 110px);
    }
    .nx-member:nth-child(even) > .nx-member__photo { grid-column: 2; grid-row: 1; }
    .nx-member:nth-child(even) > .nx-member__body  { grid-column: 1; grid-row: 1; }
    /* Pushed to whichever gutter its side of the zigzag sits on. The explicit
       width is needed because the image inside is absolutely positioned, so a
       shrink-to-fit column would collapse the frame to nothing. */
    .nx-member__photo { width: 100%; justify-self: start; }
    .nx-member:nth-child(even) > .nx-member__photo { justify-self: end; }
    /* One name per row instead of three side by side — it can carry the row */
    .nx-member__body { max-width: 52ch; }
    .nx-member__name { font-size: clamp(1.5rem, 2.4vw, 2.1rem); }
    .nx-member__bio { font-size: 1rem; }
}


/* ── Browser frame (screenshots, admin panel, live builds) ──────────────── */
.nx-frame {
    overflow: hidden;
    border-radius: 10px;
    border: 1px solid var(--nx-line);
    background: #0e0e0e;
}
.nx-dark .nx-frame { border-color: var(--nx-line-dark); }

.nx-frame__bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    background: #151515;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.nx-frame__bar i {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .18);
    display: block;
}
.nx-frame__url {
    margin-left: 10px;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .1em;
    color: var(--nx-mute-dark);
}
.nx-frame > img { width: 100%; display: block; }

/* Full-page screenshots are many times taller than they are wide — this crops
   them to the top of the page instead of stretching the frame off-screen. */
.nx-frame__view { position: relative; overflow: hidden; aspect-ratio: 16 / 10; }
/* Full-column showcase: letterboxed so a whole-page shot stays a panel
   instead of growing into a screen of its own. */
.nx-frame__view--wide { aspect-ratio: 16 / 7; }
.nx-frame__view img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
}


.nx-shots {
    display: grid;
    gap: clamp(20px, 3vw, 34px);
    margin-top: clamp(28px, 4vw, 44px);
    grid-template-columns: 1fr;
}
@media (min-width: 820px) { .nx-shots { grid-template-columns: repeat(2, 1fr); } }
.nx-shots figcaption {
    margin-top: 14px;
    font-size: .92rem;
    line-height: 1.5;
    color: var(--nx-mute);
}
.nx-dark .nx-shots figcaption { color: var(--nx-mute-dark); }

/* ── Split feature (copy beside a screenshot) ───────────────────────────── */
.nx-split {
    display: grid;
    gap: clamp(34px, 5vw, 70px);
    grid-template-columns: 1fr;
    align-items: center;
}
@media (min-width: 940px) { .nx-split { grid-template-columns: 1fr 1.05fr; } }
@media (min-width: 940px) { .nx-split--text { grid-template-columns: 1fr 1.15fr; align-items: start; } }

.nx-checks { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 13px; }
.nx-checks li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    font-size: .96rem;
    line-height: 1.5;
    color: var(--nx-mute);
}
.nx-dark .nx-checks li { color: var(--nx-mute-dark); }
.nx-checks svg { flex: 0 0 auto; margin-top: 3px; opacity: .7; }

/* Long-form prose column (about story, flow copy) */
.nx-prose {
    display: grid;
    gap: 18px;
    max-width: 58ch;
    font-size: clamp(.98rem, 1.2vw, 1.06rem);
    line-height: 1.65;
    color: var(--nx-mute);
}
.nx-dark .nx-prose { color: var(--nx-mute-dark); }
.nx-prose strong { color: inherit; font-weight: 500; }
.nx .nx-dark .nx-prose strong { color: var(--nx-white); }

/* ── Before / after compare ─────────────────────────────────────────────── */
.nx-ba { margin-top: clamp(30px, 4vw, 48px); }

.nx-ba__head {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--nx-line-dark);
}
.nx-ba__n {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    color: var(--nx-mute-dark);
}
.nx-ba__t {
    font-size: clamp(1.1rem, 1.8vw, 1.5rem);
    font-weight: 500;
    letter-spacing: -.03em;
}
.nx-ba__note {
    margin-left: auto;
    font-size: .9rem;
    color: var(--nx-mute-dark);
    text-align: right;
}
@media (max-width: 700px) { .nx-ba__note { display: none; } }

.nx-ba__view {
    position: relative;
    margin-top: 20px;
    overflow: hidden;
    border-radius: 10px;
    border: 1px solid var(--nx-line-dark);
    background: #0e0e0e;
    /* A fixed height rather than an aspect ratio: on a wide screen a 16/10 box
       runs taller than the viewport, which pushes the knob and the scrub rail
       below the fold. */
    height: clamp(340px, 64svh, 660px);
    cursor: grab;
    touch-action: none;
    user-select: none;
}
.nx-ba__view:active { cursor: grabbing; }
.nx-ba__pane {
    position: absolute;
    inset: 0;
    overflow: hidden;
}
.nx-ba__pane img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    max-width: none;
    will-change: transform;
}
/* The "before" pane is clipped from the left edge; its inner box keeps the
   full view width so the image never squashes as the handle moves. */
.nx-ba__pane--before { width: 50%; border-right: 1px solid rgba(255, 255, 255, .5); }
.nx-ba__sizer { position: absolute; top: 0; left: 0; height: 100%; }

.nx-ba__tag {
    position: absolute;
    top: 14px;
    z-index: 4;
    padding: 6px 11px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .66);
    backdrop-filter: blur(6px);
    font-family: var(--nx-mono);
    font-size: 9.5px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--nx-white);
}
.nx-ba__tag--before { left: 14px; }
.nx-ba__tag--after  { right: 14px; }

.nx-ba__knob {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 5;
    width: 42px;
    height: 42px;
    margin: -21px 0 0 -21px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--nx-white);
    color: var(--nx-black);
    cursor: ew-resize;
    box-shadow: 0 4px 18px rgba(0, 0, 0, .45);
}

/* Screenshots are full pages, far taller than the frame — this rail scrubs
   through them vertically while the knob wipes between the two versions. */
.nx-ba__prog {
    position: absolute;
    top: 14px;
    right: 4px;
    bottom: 14px;
    z-index: 5;
    /* 16px of hit area around a 4px rail — a hairline is far too small a
       target for a drag. */
    width: 16px;
    padding-inline: 6px;
    cursor: ns-resize;
}
.nx-ba__prog::before {
    content: '';
    position: absolute;
    inset: 0 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .16);
}
.nx-ba__thumb {
    position: absolute;
    left: 6px;
    right: 6px;
    min-height: 30px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .6);
}

.nx-ba__hint {
    position: absolute;
    left: 50%;
    bottom: 14px;
    z-index: 4;
    transform: translateX(-50%);
    padding: 7px 13px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .66);
    backdrop-filter: blur(6px);
    font-family: var(--nx-mono);
    font-size: 9.5px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .82);
    white-space: nowrap;
    transition: opacity .5s var(--nx-ease);
}
.nx-ba__view.is-touched .nx-ba__hint { opacity: 0; }

/* ── Marquee strip ──────────────────────────────────────────────────────── */
.nx-strip {
    overflow: hidden;
    padding-block: 18px;
    border-block: 1px solid var(--nx-line);
    white-space: nowrap;
}
.nx-dark .nx-strip { border-block-color: var(--nx-line-dark); }
.nx-strip__track {
    display: inline-flex;
    align-items: center;
    gap: 26px;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--nx-mute);
    animation: nx-strip 34s linear infinite;
}
.nx-dark .nx-strip__track { color: var(--nx-mute-dark); }
.nx-strip__track .sep { opacity: .45; }
@keyframes nx-strip { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .nx-strip__track { animation: none; } }

/* ── Filmstrip ──────────────────────────────────────────────────────────────
   A running band of real screenshots. Unlike .nx-strip, which carries words,
   this one carries the work itself — the fastest way for a services page to
   say what it makes before anyone reads a line. */
.nx-filmstrip {
    overflow: hidden;
    padding-block: clamp(18px, 2.4vw, 30px);
    border-block: 1px solid var(--nx-line);
}
.nx-dark .nx-filmstrip { border-block-color: var(--nx-line-dark); }

.nx-filmstrip__track {
    display: flex;
    width: max-content;
    gap: clamp(12px, 1.4vw, 20px);
    animation: nx-strip 52s linear infinite;
}
.nx-filmstrip:hover .nx-filmstrip__track { animation-play-state: paused; }

.nx-filmstrip figure {
    flex: 0 0 auto;
    width: clamp(230px, 27vw, 420px);
    overflow: hidden;
    border-radius: 8px;
    background: #141414;
}
.nx-filmstrip img { display: block; width: 100%; height: auto; }

@media (prefers-reduced-motion: reduce) {
    .nx-filmstrip__track { animation: none; }
}

/* ── Talk block, solo variant (no form beside it) ───────────────────────── */
.nx-talk--solo { grid-template-columns: 1fr; }
@media (min-width: 940px) { .nx-talk--solo { grid-template-columns: 1fr; } }
.nx-talk__cta { margin-top: 34px; }

/* ══════════════════════════════════════════════════════════════════════════
   ABOUT PAGE
   The about page runs dark down its top half — hero, strip, numbers and the
   chapter gallery are one unbroken black block — then hands over to white for
   the story, the journey and the team. Everything below is the furniture that
   block needs; the rest of the page reuses the shared components above.
   ══════════════════════════════════════════════════════════════════════════ */

/* A section that reads as a continuation of the one above it rather than a new
   chapter. The default block padding is tuned for a section that has to hold a
   screen on its own; stacked back to back, two of them open close to 400px of
   empty band between the last line of one and the first label of the next. */
.nx-section--stack { padding-top: clamp(44px, 5.5vw, 90px); }

/* Hero top line: the ( About ) slug and the founding date share a row and run
   to both gutters, so the hero opens with a rule of type rather than a label
   floating on its own. */
.nx-phero__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: clamp(22px, 3vw, 34px);
    padding-bottom: 16px;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-phero__row,
.nx-phero--dark .nx-phero__row { border-bottom-color: var(--nx-line-dark); }
.nx-phero__row .nx-phero__slug { margin-bottom: 0; }

/* Scroll cue — a mono word with a hairline that pulses down under it. */
.nx-cue {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-cue,
.nx-phero--dark .nx-cue { color: var(--nx-mute-dark); }
.nx-cue::after {
    content: '';
    width: 1px;
    height: 26px;
    background: currentColor;
    transform-origin: 50% 0;
    animation: nx-cue 2.4s var(--nx-ease-io) infinite;
}
@keyframes nx-cue {
    0%, 100% { transform: scaleY(.25); opacity: .35; }
    45%      { transform: scaleY(1);   opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .nx-cue::after { animation: none; } }

/* ── Chapter gallery ────────────────────────────────────────────────────────
   Two columns that never line up: the right one starts a long way down and
   every following card drops further still, so the eye is walked down the page
   diagonally instead of scanning a grid. Each chapter is a link — the whole
   card is the hit area, and the EXPLORE label is the affordance. */
.nx-chaps {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(46px, 7vw, 84px);
    margin-top: clamp(38px, 5vw, 62px);
}
@media (min-width: 900px) {
    .nx-chaps {
        grid-template-columns: repeat(2, 1fr);
        column-gap: clamp(34px, 5vw, 90px);
        row-gap: 0;
    }
    /* The stagger. Odd cards ride the left column and step down in pairs;
       even cards start dropped and follow them, so no two card tops ever
       share a line. */
    .nx-chaps > :nth-child(2n)   { margin-top: clamp(80px, 13vw, 210px); }
    .nx-chaps > :nth-child(n+3)  { margin-top: clamp(-40px, -4vw, 0px); }
    .nx-chaps > :nth-child(2n+3) { margin-top: clamp(40px, 6vw, 96px); }
}

.nx-chap { display: block; }

.nx-chap__k {
    display: block;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-chap__k { color: var(--nx-mute-dark); }

.nx-chap__t {
    margin-top: 14px;
    max-width: 20ch;
    font-size: clamp(1.35rem, 2.5vw, 2.15rem);
    font-weight: 500;
    line-height: 1.06;
    letter-spacing: -.035em;
}

.nx-chap__media {
    position: relative;
    margin-top: clamp(20px, 2.6vw, 32px);
    overflow: hidden;
    border-radius: 10px;
    background: #141414;
    aspect-ratio: 4 / 5;
}
/* Ratios alternate down the column so the stack never reads as a grid of
   identical windows. */
.nx-chaps > :nth-child(2) .nx-chap__media { aspect-ratio: 1 / 1; }
.nx-chaps > :nth-child(3) .nx-chap__media { aspect-ratio: 5 / 4; }

/* Deliberately not a .nx-par frame: the parallax writes `transform` from a
   custom property, and the hover push-in needs that same channel. */
.nx-chap__media > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 1.1s var(--nx-ease);
}
.nx-chap:hover .nx-chap__media > img { transform: scale(1.045); }

/* Veil — sits between the picture and the label so the mono type keeps its
   contrast whatever the photograph is doing underneath. */
.nx-chap__media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .28);
    opacity: 0;
    transition: opacity .6s var(--nx-ease);
    pointer-events: none;
}
.nx-chap:hover .nx-chap__media::after { opacity: 1; }

.nx-chap__go {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--nx-white);
    pointer-events: none;
}
.nx-chap__go svg { transition: transform .5s var(--nx-ease); }
.nx-chap:hover .nx-chap__go svg { transform: translateX(7px); }

/* On a pointer device the label is the reward for hovering; on touch there is
   no hover to reward, so it simply stays on. */
@media (hover: hover) {
    .nx-chap__go {
        opacity: 0;
        transform: translateY(10px);
        transition: opacity .5s var(--nx-ease), transform .5s var(--nx-ease);
    }
    .nx-chap:hover .nx-chap__go { opacity: 1; transform: none; }
}


/* ── Photo duo ──────────────────────────────────────────────────────────────
   RECONSTRUCTED. The original of this block was uncommitted work that was lost
   when the stream refactor removed it; git had no copy to restore from. The
   shape below matches how about.html uses it (two captioned .nx-par frames,
   the second dropped), but the exact numbers are a best reconstruction — worth
   an eye before committing. */
.nx-duo {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(30px, 4vw, 48px);
    margin-top: clamp(38px, 5vw, 62px);
}
@media (min-width: 700px) {
    .nx-duo { grid-template-columns: repeat(2, 1fr); }
    .nx-duo > :nth-child(2) { margin-top: clamp(50px, 8vw, 130px); }
}
.nx-duo__frame {
    position: relative;
    overflow: hidden;
    border-radius: 10px;
    aspect-ratio: 4 / 5;
    background: #161616;
}
.nx-duo__cap {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    font-family: var(--nx-mono);
    font-size: 10.5px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-duo__cap { color: var(--nx-mute-dark); }

/* ── Creed (values) ─────────────────────────────────────────────────────────
   Six rows instead of six boxes. Hovering one sweeps a white panel up behind
   it and the row inverts, which is the same move the pills make — the page
   only has the one hover idiom. */
.nx-creed {
    margin-top: clamp(34px, 4.5vw, 56px);
    border-top: 1px solid var(--nx-line);
}
.nx-dark .nx-creed { border-top-color: var(--nx-line-dark); }

.nx-creed__row {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    padding: clamp(24px, 3vw, 38px) clamp(16px, 2vw, 30px);
    border-bottom: 1px solid var(--nx-line);
    isolation: isolate;
    transition: color .5s var(--nx-ease);
}
.nx-dark .nx-creed__row { border-bottom-color: var(--nx-line-dark); }

@media (min-width: 860px) {
    .nx-creed__row {
        grid-template-columns: 4.5rem minmax(0, 1fr) minmax(0, 1.25fr);
        gap: clamp(20px, 3vw, 48px);
        align-items: baseline;
    }
}

/* The sweep is whatever the section is not: black panel on the white ground,
   white panel on the dark one. */
.nx-creed__row::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--nx-black);
    transform: scaleY(0);
    transform-origin: 50% 100%;
    transition: transform .55s var(--nx-ease);
}
.nx-creed__row:hover::before { transform: scaleY(1); }
.nx-creed__row:hover { color: var(--nx-white); }
.nx-dark .nx-creed__row::before { background: var(--nx-white); }
.nx-dark .nx-creed__row:hover { color: var(--nx-black); }

.nx-creed__n {
    font-family: var(--nx-mono);
    font-size: 11px;
    letter-spacing: .12em;
    color: var(--nx-mute);
    transition: color .5s var(--nx-ease);
}
.nx-dark .nx-creed__n { color: var(--nx-mute-dark); }
.nx-creed__row:hover .nx-creed__n { color: inherit; }

.nx-creed__t {
    font-size: clamp(1.25rem, 2.4vw, 2rem);
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: -.035em;
}

.nx-creed__d {
    max-width: 52ch;
    font-size: .94rem;
    line-height: 1.55;
    color: var(--nx-mute);
    transition: color .5s var(--nx-ease);
}
.nx-dark .nx-creed__d { color: var(--nx-mute-dark); }
.nx-creed__row:hover .nx-creed__d { color: inherit; }

/* ── Milestones ─────────────────────────────────────────────────────────────
   The journey as a stack of rules, the year carrying it at display size. The
   year greys out until its row is hovered, so the column reads as a timeline
   with one live entry rather than four equal shouts. */
.nx-mile {
    margin-top: clamp(34px, 4.5vw, 56px);
    border-top: 1px solid var(--nx-line);
}
.nx-dark .nx-mile { border-top-color: var(--nx-line-dark); }

.nx-mile__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    padding-block: clamp(26px, 3.4vw, 44px);
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-mile__row { border-bottom-color: var(--nx-line-dark); }

@media (min-width: 860px) {
    .nx-mile__row {
        grid-template-columns: minmax(0, 11rem) minmax(0, 1fr) minmax(0, 1.3fr);
        gap: clamp(20px, 3vw, 48px);
        align-items: start;
    }
}

.nx-mile__y {
    font-size: clamp(2.4rem, 5.5vw, 4.4rem);
    font-weight: 600;
    line-height: .9;
    letter-spacing: -.05em;
    color: var(--nx-mute);
    transition: color .5s var(--nx-ease), transform .6s var(--nx-ease);
}
.nx-dark .nx-mile__y { color: var(--nx-mute-dark); }
.nx-mile__row:hover .nx-mile__y {
    color: inherit;
    transform: translateX(6px);
}

.nx-mile__t {
    font-size: clamp(1.1rem, 1.8vw, 1.5rem);
    font-weight: 500;
    letter-spacing: -.03em;
    padding-top: .18em;
}
.nx-mile__d {
    max-width: 52ch;
    font-size: .94rem;
    line-height: 1.55;
    color: var(--nx-mute);
    padding-top: .3em;
}
.nx-dark .nx-mile__d { color: var(--nx-mute-dark); }

/* ── Team, about-page treatment ─────────────────────────────────────────────
   The three portraits were shot years and cameras apart — a shop, a mirror, a
   studio backdrop. Desaturating them is what makes the row read as one team
   rather than three found photographs; colour comes back on hover, so the
   picture is still the real one. */
.nx-member__photo > img {
    filter: grayscale(1) contrast(1.04);
    transition: filter .7s var(--nx-ease);
}
.nx-member:hover .nx-member__photo > img { filter: none; }

/* Tags read as a footnote until the card is hovered */
.nx-member .nx-tags { transition: opacity .5s var(--nx-ease); }
@media (hover: hover) {
    .nx-member .nx-tags { opacity: .55; }
    .nx-member:hover .nx-tags { opacity: 1; }
}


/* ══════════════════════════════════════════════════════════════════════════
   LEGAL DOCUMENTS
   The privacy / terms / cookie markup is kept as-is; only its skin changes.
   ══════════════════════════════════════════════════════════════════════════ */

/* Each document carries both language versions; hide the one that does not
   match <html lang>. I18n.js sets it, the inline head script pre-sets it. */
html[lang='cs'] [data-doclang='en'],
html[lang='en'] [data-doclang='cs'] { display: none; }

.nx-legal {
    display: grid;
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 5rem);
    align-items: start;
    padding-block: clamp(60px, 8vw, 110px) clamp(80px, 11vw, 150px);
}
@media (max-width: 900px) { .nx-legal { grid-template-columns: 1fr; } }

/* ── Index column ── */
.nx .lg-toc {
    position: sticky;
    top: calc(var(--nx-bar) + 20px);
    border-left: 1px solid var(--nx-line);
    padding-left: 20px;
}
.nx-dark .lg-toc { border-left-color: var(--nx-line-dark); }

.nx .lg-toc-label {
    display: block;
    margin-bottom: 18px;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .lg-toc-label { color: var(--nx-mute-dark); }

.nx .lg-toc ol { list-style: none; counter-reset: lgtoc; margin: 0; padding: 0; }
.nx .lg-toc li { counter-increment: lgtoc; }
.nx .lg-toc a {
    display: block;
    padding: 7px 0;
    font-size: .88rem;
    line-height: 1.4;
    letter-spacing: -.015em;
    color: var(--nx-mute);
    transition: color .3s ease;
}
.nx-dark .lg-toc a { color: var(--nx-mute-dark); }
.nx .lg-toc a::before {
    content: counter(lgtoc, decimal-leading-zero);
    margin-right: 12px;
    font-family: var(--nx-mono);
    font-size: 10px;
    opacity: .55;
}
.nx .lg-toc a:hover { color: var(--nx-black); }
.nx .nx-dark .lg-toc a:hover { color: var(--nx-white); }

@media (max-width: 900px) {
    .nx .lg-toc {
        position: static;
        border-left: 0;
        border-bottom: 1px solid var(--nx-line);
        padding: 0 0 26px;
    }
    .nx-dark .lg-toc { border-bottom-color: var(--nx-line-dark); }
    .nx .lg-toc ol { columns: 2; column-gap: 24px; }
}
@media (max-width: 560px) { .nx .lg-toc ol { columns: 1; } }

/* ── The document ── */
.nx .lg-doc {
    max-width: 68ch;
    font-size: clamp(.95rem, 1.15vw, 1.02rem);
    line-height: 1.75;
    color: var(--nx-mute);
}
.nx-dark .lg-doc { color: var(--nx-mute-dark); }

.nx .lg-doc > div > section { scroll-margin-top: calc(var(--nx-bar) + 24px); }
.nx .lg-doc > div > section + section { margin-top: clamp(44px, 6vw, 70px); }

.nx .lg-doc h2 {
    margin-bottom: 18px;
    font-size: clamp(1.2rem, 2vw, 1.6rem);
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: -.035em;
    color: var(--nx-black);
}
.nx .nx-dark .lg-doc h2 { color: var(--nx-white); }

.nx .lg-doc h2 .lg-num {
    margin-right: 14px;
    font-family: var(--nx-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .1em;
    color: var(--nx-mute);
    vertical-align: .3em;
}
.nx-dark .lg-doc h2 .lg-num { color: var(--nx-mute-dark); }

.nx .lg-doc h3 {
    margin: 30px 0 10px;
    font-size: 1rem;
    font-weight: 500;
    letter-spacing: -.02em;
    color: var(--nx-black);
}
.nx .nx-dark .lg-doc h3 { color: var(--nx-white); }

.nx .lg-doc p { margin-bottom: 16px; }
.nx .lg-doc > div > section > *:last-child { margin-bottom: 0; }

.nx .lg-doc strong { font-weight: 500; color: var(--nx-black); }
.nx .nx-dark .lg-doc strong { color: var(--nx-white); }

.nx .lg-doc a {
    border-bottom: 1px solid var(--nx-line);
    color: inherit;
    transition: border-color .3s ease, color .3s ease;
}
.nx-dark .lg-doc a { border-bottom-color: var(--nx-line-dark); }
.nx .lg-doc a:hover { color: var(--nx-black); border-bottom-color: currentColor; }
.nx .nx-dark .lg-doc a:hover { color: var(--nx-white); }

.nx .lg-doc ul { list-style: none; margin: 0 0 16px; padding: 0; }
.nx .lg-doc li { position: relative; padding-left: 20px; margin-bottom: 9px; }
.nx .lg-doc li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .82em;
    width: 8px;
    height: 1px;
    background: currentColor;
    opacity: .5;
}
.nx .lg-doc li:last-child { margin-bottom: 0; }

.nx .lg-note {
    margin: 24px 0;
    padding: 20px 22px;
    border: 1px solid var(--nx-line);
    border-left-width: 2px;
    border-radius: 6px;
    font-size: .92rem;
    line-height: 1.65;
}
.nx-dark .lg-note { border-color: var(--nx-line-dark); background: rgba(255, 255, 255, .025); }
.nx .lg-note p:last-child { margin-bottom: 0; }

/* Placeholders the studio still has to fill in — deliberately loud */
.nx .lg-fill {
    font-family: var(--nx-mono);
    font-size: .86em;
    white-space: nowrap;
    border-bottom: 1px dashed currentColor;
    opacity: .85;
}

.nx .lg-defs {
    display: grid;
    grid-template-columns: minmax(6.5rem, auto) 1fr;
    gap: 10px 26px;
    margin: 22px 0;
    padding: 22px 24px;
    border: 1px solid var(--nx-line);
    border-radius: 6px;
    font-size: .92rem;
}
.nx-dark .lg-defs { border-color: var(--nx-line-dark); background: rgba(255, 255, 255, .025); }
.nx .lg-defs dt {
    padding-top: .3em;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .lg-defs dt { color: var(--nx-mute-dark); }
.nx .lg-defs dd { margin: 0; }
@media (max-width: 560px) {
    .nx .lg-defs { grid-template-columns: 1fr; gap: 2px 0; }
    .nx .lg-defs dd { margin-bottom: 14px; }
    .nx .lg-defs dd:last-child { margin-bottom: 0; }
}

.nx .lg-table-wrap {
    margin: 24px 0;
    overflow-x: auto;
    border: 1px solid var(--nx-line);
    border-radius: 6px;
    -webkit-overflow-scrolling: touch;
}
.nx-dark .lg-table-wrap { border-color: var(--nx-line-dark); }
.nx .lg-table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: .86rem; line-height: 1.5; }
.nx .lg-table th,
.nx .lg-table td {
    padding: 14px 16px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .lg-table th,
.nx-dark .lg-table td { border-bottom-color: var(--nx-line-dark); }
.nx .lg-table thead th {
    font-family: var(--nx-mono);
    font-size: 9.5px;
    font-weight: 400;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--nx-mute);
    white-space: nowrap;
}
.nx-dark .lg-table thead th { color: var(--nx-mute-dark); background: rgba(255, 255, 255, .03); }
.nx .lg-table tbody tr:last-child th,
.nx .lg-table tbody tr:last-child td { border-bottom: 0; }
.nx .lg-table tbody th { font-weight: 500; white-space: nowrap; color: var(--nx-black); }
.nx .nx-dark .lg-table tbody th { color: var(--nx-white); }
.nx .lg-table code { font-family: var(--nx-mono); font-size: .92em; }

.nx .lg-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

/* Reuse the pill for the document's own buttons */
.nx .lg-doc .lg-btn,
.nx .lg-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 22px;
    border: 1px solid var(--nx-line);
    border-radius: 999px;
    background: none;
    cursor: pointer;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: inherit;
    transition: border-color .35s var(--nx-ease), color .35s var(--nx-ease);
}
.nx-dark .lg-btn { border-color: var(--nx-line-dark); }
.nx .lg-doc .lg-btn:hover,
.nx .lg-btn:hover { border-color: currentColor; color: var(--nx-black); }
.nx .nx-dark .lg-btn:hover { color: var(--nx-white); }

.nx .lg-siblings {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 14px;
    margin-top: clamp(46px, 6vw, 72px);
    padding-top: clamp(28px, 4vw, 42px);
    border-top: 1px solid var(--nx-line);
}
.nx-dark .lg-siblings { border-top-color: var(--nx-line-dark); }

.nx .lg-doc .lg-sibling,
.nx .lg-sibling {
    padding: 20px 22px;
    border: 1px solid var(--nx-line);
    border-radius: 8px;
    transition: border-color .4s var(--nx-ease), background .4s var(--nx-ease);
}
.nx-dark .lg-sibling { border-color: var(--nx-line-dark); }
.nx .lg-doc .lg-sibling:hover,
.nx .lg-sibling:hover { border-color: currentColor; background: rgba(255, 255, 255, .03); }
.nx .lg-sibling span {
    display: block;
    margin-bottom: 10px;
    font-family: var(--nx-mono);
    font-size: 9.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .lg-sibling span { color: var(--nx-mute-dark); }
.nx .lg-sibling strong {
    font-size: 1rem;
    font-weight: 500;
    letter-spacing: -.025em;
    color: var(--nx-black);
}
.nx .nx-dark .lg-sibling strong { color: var(--nx-white); }

/* ── Live-build showcase (services/web-development.html) ────────────────────
   A laptop and a phone carrying the same production site, each scrolling its
   own capture as the pair crosses the viewport.

   The plates are full-page screenshots, not footage. Scrubbing an mp4 from
   scroll position needs a keyframe on virtually every frame before it will
   seek cleanly, which multiplies the file several times over, and iOS still
   will not do it smoothly once the file is that big. A tall WebP is a fifth of
   the bytes, decodes once, and then only ever moves on the compositor.

   The section pins. Each showcase is a tall spacer whose viewport sticks to
   the top of the screen for the length of the run, and the plates travel while
   it is held — enter the section and the site starts reading itself out, and
   when it has finished the pin lets go and the page carries on. Same two modes
   as the rail above: without .is-pinned the spacer collapses to its content and
   the plates sit still at the hero.

   The script writes one number per stage — `--p`, 0 to 1 across the pinned run
   — and the arithmetic lives here. Nothing is measured at runtime: every desktop
   plate is cut to exactly 1400×4100 and every phone plate to 560×3600, so how
   much of each has to pass its aperture is a constant, not a measurement.

   `--p` trails the scroll by a few frames rather than tracking it exactly; the
   easing is in js/nx.js and the reason is that the aperture magnifies the
   scroll about threefold, so a step nobody notices on the page is a jolt
   inside the glass. Nothing here has to know — the number still runs 0 to 1,
   it just gets there smoothly.

   Both plates share the one `--p`, so the desktop and the mobile view of a
   site stay at the same point in the page as they travel. That is the whole
   argument the pair is making — same site, same moment, two widths.
   ───────────────────────────────────────────────────────────────────────── */
.nx-show {
    /* Fraction of each plate that has to pass its aperture. The apertures are
       cut to the recordings rather than to a nominal 16:10, so the footage
       fills the glass and the fallback capture behind it lines up exactly:
       desktop  1 − (1400 × 700/1280) / 4100   phone  1 − (560 × 862/400) / 3600 */
    --nx-show-run:  .8132;
    --nx-show-prun: .6648;
    position: relative;
    margin-top: clamp(58px, 8vw, 108px);
}
.nx-show:first-of-type { margin-top: clamp(32px, 4vw, 52px); }

/* The spacer. --show-run is how far this site has to travel expressed as scroll
   distance; js/nx.js writes it here, and one screen on top of it is the length
   the pinned viewport holds. Both ends are stated in the same svh the viewport
   is sized in, so a phone hiding its address bar cannot leave the pin running
   past the end of the capture. */
.nx-show.is-pinned {
    height: calc(100svh + var(--show-run, 0px));
    margin-top: clamp(34px, 4.5vw, 68px);
}

.nx-show__vp { position: relative; }

/* Held to the top for the whole run. The page header is fixed over the top of
   the screen, so the run's content is centred in what is left below it rather
   than in the full height — otherwise the caption sits under the menu at every
   viewport short enough to matter. */
.nx-show.is-pinned .nx-show__vp {
    position: sticky;
    top: 0;
    height: 100svh;
    box-sizing: border-box;
    padding-top: var(--nx-bar);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.nx-show__lede {
    max-width: 58ch;
    margin-top: 18px;
    font-size: clamp(1rem, 1.5vw, 1.16rem);
    line-height: 1.55;
    color: var(--nx-mute);
}
.nx-dark .nx-show__lede { color: var(--nx-mute-dark); }

.nx-show__head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 14px;
    padding-bottom: 15px;
    border-bottom: 1px solid var(--nx-line);
}
.nx-dark .nx-show__head { border-bottom-color: var(--nx-line-dark); }

.nx-show__idx {
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .14em;
    color: var(--nx-mute);
}
.nx-show__name {
    margin: 0;
    font-size: clamp(1.35rem, 3vw, 2.15rem);
    font-weight: 500;
    letter-spacing: -.035em;
}
.nx-show__meta {
    margin-left: auto;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--nx-mute);
}
.nx-dark .nx-show__meta,
.nx-dark .nx-show__idx { color: var(--nx-mute-dark); }

/* The phone hangs past the foot of the deck, so the stage carries the room for
   it rather than letting it overlap whatever section comes next. */
.nx-show__stage {
    position: relative;
    /* Sized against the viewport's height, not the column's width. A 16:10
       aperture spanning the full shell is taller than most screens, so the
       lid, the deck and the handset never share a frame and the thing stops
       reading as a laptop — you just get a picture with a dark edge. Capping
       the stage so the whole device fits in about three quarters of the screen
       is what makes it a device rather than a panel. */
    max-width: min(100%, 138vh);
    margin-inline: auto;
    margin-top: clamp(24px, 3.4vw, 42px);
    padding-bottom: clamp(26px, 4.5vw, 52px);
}
/* Pinned there is a hard ceiling: the caption, the device and the link all have
   to sit in one screen under the header. Sizing the stage off svh is what keeps
   the deck and the handset on screen instead of pushing them past the fold. */
.nx-show.is-pinned .nx-show__stage {
    max-width: min(100%, 112svh);
    margin-top: clamp(18px, 2.4vw, 30px);
    padding-bottom: clamp(20px, 3vw, 38px);
}

/* ── The laptop ── bezel is padding, so the aperture inside holds 16:10 at any
   column width and the lid grows with it. */
.nx-show__lap {
    position: relative;
    padding: clamp(7px, .95vw, 13px);
    padding-bottom: clamp(15px, 1.9vw, 25px);   /* the chin */
    border-radius: clamp(9px, 1vw, 15px);
    background: linear-gradient(#262626, #131313);
    border: 1px solid rgba(255, 255, 255, .10);
    box-shadow: 0 36px 74px -32px rgba(0, 0, 0, .72);
}
/* Wordmark strip on the chin — enough to read as a lid without drawing a logo
   that would compete with the site inside it. */
.nx-show__lap::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: clamp(6px, .72vw, 10px);
    width: 34px;
    height: 3px;
    margin-left: -17px;
    border-radius: 2px;
    background: rgba(255, 255, 255, .13);
}

.nx-show__screen {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    aspect-ratio: 1280 / 700;
    border-radius: 3px;
    background: #000;
}
/* The footage rides in the same aperture, over the capture. It is revealed only
   once it can actually be seeked, so a slow connection shows the plate scrubbing
   underneath rather than a black rectangle, and the handover is invisible. Both
   are driven by the same `--p`, so they are never at different points in the
   site — whichever one you are looking at, it is the same frame.

   Touch gets a smaller cut of the same footage rather than none of it; the
   plate stays underneath either way, and stays the whole of it when the
   footage is refused. See `film()` in js/nx.js for what refuses it. */
.nx-show__screen video,
.nx-show__pscreen video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity .45s var(--nx-ease);
}
.nx-show__screen video.is-ready,
.nx-show__pscreen video.is-ready { opacity: 1; }

/* All three of these sites are near-black, and so is the bezel around them —
   without a hairline the glass has no edge and the lid reads as a flat panel.
   It rides above the plate, so it stays put while the capture travels. */
.nx-show__screen::after,
.nx-show__pscreen::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    border-radius: inherit;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .085);
}
.nx-show__screen img {
    display: block;
    width: 100%;
    height: auto;
    /* -100% is the plate's own height; the constant is the share of it that
       has to cross the aperture, and `--p` is how far through that we are. */
    transform: translate3d(0, calc(-100% * var(--nx-show-run) * var(--p, 0)), 0);
}

/* The base: only a little wider than the lid, tapering to the front edge. It
   wants to overhang just enough to read as a separate part — push it much past
   that and it stops looking attached to the lid and starts looking like a bar
   lying behind it. */
.nx-show__deck {
    position: relative;
    width: 105.5%;
    margin-left: -2.75%;
    height: clamp(10px, 1.3vw, 17px);
    border-radius: 0 0 clamp(7px, .9vw, 12px) clamp(7px, .9vw, 12px);
    background: linear-gradient(#3a3a3a 0%, #232323 22%, #141414 68%, #0b0b0b 100%);
    clip-path: polygon(0 0, 100% 0, 98.2% 100%, 1.8% 100%);
    /* Grounds the device instead of leaving it floating on the band. */
    box-shadow: 0 26px 34px -22px rgba(0, 0, 0, .55);
}
/* The finger notch on the front edge. */
.nx-show__deck::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 0;
    width: 10%;
    height: clamp(3px, .4vw, 5px);
    margin-left: -5%;
    border-radius: 0 0 6px 6px;
    background: rgba(0, 0, 0, .5);
}

/* ── The phone ── overlapping the lower right corner, on the same `--p`. */
.nx-show__phone {
    position: absolute;
    z-index: 2;
    right: -1.5%;
    bottom: 0;
    width: 17.5%;
    min-width: 62px;
    padding: clamp(2px, .3vw, 4px);
    border-radius: clamp(10px, 1.5vw, 20px);
    background: linear-gradient(#2c2c2c, #131313);
    border: 1px solid rgba(255, 255, 255, .12);
    box-shadow: 0 22px 42px -18px rgba(0, 0, 0, .78);
}
.nx-show__pscreen {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    aspect-ratio: 400 / 862;
    border-radius: clamp(8px, 1.25vw, 17px);
    background: #000;
}
.nx-show__pscreen img {
    display: block;
    width: 100%;
    height: auto;
    transform: translate3d(0, calc(-100% * var(--nx-show-prun) * var(--p, 0)), 0);
}

.nx-show__go { margin-top: clamp(16px, 2vw, 24px); padding-inline: 0; }

/* On a phone the laptop is only a few hundred pixels wide and 17.5% of that is
   a sliver — give the handset back some size and let the caption wrap. */
@media (max-width: 620px) {
    .nx-show__phone { width: 22%; right: -2%; }
    .nx-show__meta { width: 100%; margin-left: 0; }
}

/* Without motion — or without a compositor to move two tall plates on — the
   plates simply sit at the top of each capture, which is the hero of the site
   and the frame worth showing if only one is going to be seen. */
@media (prefers-reduced-motion: reduce) {
    .nx-show__screen img,
    .nx-show__pscreen img { transform: none; }
}
.lowfx .nx-show__screen img,
.lowfx .nx-show__pscreen img { transform: none; }


/* ── Low-FX ── see the block at the foot of nx.css for what sets .lowfx and
   why. Here it is the two labels floating over the before/after screenshots:
   both sit on media that moves under the handle, so their backdrop is re-read
   and re-blurred through the whole drag. */
.lowfx .nx-ba__tag,
.lowfx .nx-ba__hint {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: rgba(0, 0, 0, .82);
}
.lowfx .nx-ba__pane img { will-change: auto; }
