/* ==========================================================================
   vb-instagram — Instagram band, rendered on every page from _Layout.
   Data: /data/instagram.json  •  Images: /ProductPictures/instagram/*.webp

   Two constraints shape every decision below:
   1. Persia cannot reach any CDN, so: no webfont hosts, no icon fonts, no JS
      libraries. Type is the site's own local Shabnam/Lalezar; icons are inline
      SVG; motion is hand-rolled.
   2. The band sits inside the legacy theme (bootstrap + style.min.css), which
      has loose global rules for section/figure/button/ul. Everything here is
      scoped under .vb-ig and resets what it needs rather than trusting cascade.

   Palette is sampled from the BORDERLESS monogram (wwwroot/.../instagram/
   avatar.webp), not chosen: #F0C078 / #D8A860 / #A87848 are the literal golds
   in the client's own logo gradient.
   ========================================================================== */

.vb-ig {
    --ig-ink: #09090B;
    --ig-surface: #141417;
    --ig-bone: #EFEAE2;
    --ig-mute: #8C8A93;
    --ig-brass: #D8A860;
    --ig-brass-lit: #F0C078;
    --ig-brass-deep: #A87848;
    --ig-line: rgba(240, 192, 120, .14);
    --ig-row: 13.5rem;

    direction: rtl;
    position: relative;
    isolation: isolate;
    padding: clamp(2.5rem, 5.5vw, 4rem) 0 clamp(2rem, 4vw, 3rem);
    /* Lifted off the page's black and closed with a brass hairline, so the band
       reads as its own room. On a near-black page a flat near-black section is
       invisible as a section. */
    background: linear-gradient(180deg, #101015 0%, var(--ig-ink) 62%);
    border-top: 1px solid var(--ig-line);
    color: var(--ig-bone);
    overflow: hidden;
    font-family: Shabnam, Tahoma, sans-serif;

    /* The band is on every page and always below the fold. Skip rendering it
       until it is near the viewport; contain-intrinsic-size reserves its height
       so the scrollbar does not jump when it does render. Costs nothing on the
       pages nobody scrolls. */
    content-visibility: auto;
    contain-intrinsic-size: auto 44rem;
}

/* A single brass wash bleeding from the top-right — the only ambient effect in
   the band. Sits behind content via z-index on an ::before so it never
   intercepts pointer events on the rail. */
.vb-ig::before {
    content: "";
    position: absolute;
    inset: -40% -10% auto -10%;
    height: 70%;
    background: radial-gradient(58% 100% at 80% 0%, rgba(216, 168, 96, .22), transparent 68%);
    pointer-events: none;
    z-index: -1;
}

.vb-ig__wrap {
    max-width: 84rem;
    margin: 0 auto;
    padding: 0 clamp(1rem, 4vw, 2.5rem);
}

/* ---------- profile plate ---------- */

/* Capped and pinned to the inline start. Left to stretch the full 84rem it put
   ~800px of nothing between the identity and the follow button, which reads as
   a broken grid rather than as space. Instagram caps its own profile header for
   the same reason; the rail below stays full width, and that contrast is what
   makes the asymmetry look chosen. */
.vb-ig__head {
    display: flex;
    align-items: center;
    gap: clamp(.9rem, 2vw, 1.4rem);
    margin-bottom: clamp(1.4rem, 2.6vw, 2rem);
    max-width: 46rem;
    margin-inline-end: auto;
}

.vb-ig__avatar {
    flex: 0 0 auto;
    width: clamp(3.6rem, 7vw, 4.75rem);
    aspect-ratio: 1;
    border-radius: 50%;
    padding: 2.5px;
    background: conic-gradient(from 210deg, var(--ig-brass-deep), var(--ig-brass-lit), var(--ig-brass), var(--ig-brass-deep));
    display: grid;
    place-items: center;
}

.vb-ig__avatar img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    border: 2.5px solid var(--ig-ink);
    background: var(--ig-ink);
}

.vb-ig__id {
    min-width: 0;
    flex: 1 1 auto;
}

/* The handle is an identifier, so it is set in mono — the one Latin face in the
   band. Left-to-right inside an RTL parent. */
.vb-ig__handle {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    direction: ltr;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: clamp(.63rem, 1.5vw, .74rem);
    letter-spacing: .02em;
    color: var(--ig-brass);
    text-decoration: none;
    margin-bottom: .3rem;
}

.vb-ig__handle:hover { color: var(--ig-brass-lit); }

.vb-ig__dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--ig-brass);
    box-shadow: 0 0 0 0 rgba(216, 168, 96, .7);
    animation: vb-ig-pulse 2.4s ease-out infinite;
}

@keyframes vb-ig-pulse {
    70%  { box-shadow: 0 0 0 7px rgba(216, 168, 96, 0); }
    100% { box-shadow: 0 0 0 0 rgba(216, 168, 96, 0); }
}

.vb-ig__title {
    font-family: Lalezar, Shabnam, Tahoma, sans-serif;
    font-size: clamp(1.35rem, 3.4vw, 2rem);
    font-weight: 400;
    line-height: 1.25;
    margin: 0 0 .3rem;
    color: var(--ig-bone);
}

.vb-ig__sub {
    margin: 0;
    font-size: clamp(.78rem, 1.9vw, .9rem);
    line-height: 1.8;
    color: var(--ig-mute);
}

.vb-ig__follow {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .72rem 1.15rem;
    border-radius: 999px;
    border: 1px solid var(--ig-line);
    background: linear-gradient(180deg, rgba(240, 192, 120, .12), rgba(240, 192, 120, .04));
    color: var(--ig-brass-lit);
    font-family: inherit;
    font-size: .82rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color .25s, background .25s, transform .25s;
}

.vb-ig__follow:hover {
    color: var(--ig-brass-lit);
    border-color: rgba(240, 192, 120, .4);
    background: linear-gradient(180deg, rgba(240, 192, 120, .2), rgba(240, 192, 120, .07));
    transform: translateY(-1px);
}

.vb-ig__follow svg { width: 1rem; height: 1rem; }

/* ---------- rails ----------
   Two rails drifting against each other. Native overflow scroll (not a transform
   track) so swipe, trackpad, keyboard and screen-reader scrolling all work for
   free; the drift in vb-instagram.js nudges scrollLeft on top of it, and each
   rail reads its own direction from data-dir. Deliberately NO scroll-snap:
   snapping fights the programmatic drift and the seamless wrap.

   Full-bleed by design — the rails run wider than the capped header, and that
   contrast is what makes the header's asymmetry read as chosen. */

.vb-ig__rails {
    display: flex;
    flex-direction: column;
    gap: .7rem;
}

.vb-ig__rail {
    display: flex;
    gap: .7rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding-inline: clamp(1rem, 4vw, 2.5rem);
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    cursor: grab;
}

.vb-ig__rail::-webkit-scrollbar { display: none; }
.vb-ig__rail.is-drag { cursor: grabbing; }

/* Edge-to-edge on phones: the band must have zero side gutters. */
@media (max-width: 700px) {
    .vb-ig__rail { padding-inline: .6rem; }
}

/* Fixed row height, natural width. aspect-ratio is set per card from the
   manifest's intrinsic size — the source frames run 0.75 to 1.78, and a uniform
   square would crop the composition out of most of them. */
.vb-ig__card {
    flex: 0 0 auto;
    height: var(--ig-row);
    width: auto;
    position: relative;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 12px;
    overflow: hidden;
    background: var(--ig-surface);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform .45s cubic-bezier(.2, .7, .3, 1), box-shadow .45s;
}

.vb-ig__card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .7s cubic-bezier(.2, .7, .3, 1), filter .45s;
    filter: saturate(.94);
}

/* The scrim only exists to make a caption legible, so it arrives with the
   caption. At rest the photograph is unobstructed. */
.vb-ig__card::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(9, 9, 11, .88) 0%, rgba(9, 9, 11, .15) 46%, transparent 70%);
    opacity: 0;
    transition: opacity .45s;
}

.vb-ig__card:hover,
.vb-ig__card:focus-visible {
    transform: translateY(-5px);
    box-shadow: 0 18px 44px -14px rgba(0, 0, 0, .9), 0 0 0 1px var(--ig-line);
    outline: none;
}

.vb-ig__card:focus-visible { box-shadow: 0 0 0 2px var(--ig-brass-lit); }
.vb-ig__card:hover img,
.vb-ig__card:focus-visible img { transform: scale(1.05); filter: saturate(1.03); }
.vb-ig__card:hover::after,
.vb-ig__card:focus-visible::after { opacity: 1; }

.vb-ig__cap {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    padding: .85rem .9rem;
    font-size: .74rem;
    line-height: 1.65;
    color: var(--ig-bone);
    text-align: start;
    z-index: 1;
    transform: translateY(.5rem);
    opacity: 0;
    transition: transform .45s cubic-bezier(.2, .7, .3, 1), opacity .45s;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    pointer-events: none;
}

.vb-ig__card:hover .vb-ig__cap,
.vb-ig__card:focus-visible .vb-ig__cap { transform: translateY(0); opacity: 1; }

/* ---------- story viewer (the signature) ---------- */

.vb-ig-lb {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: none;
    background: rgba(4, 4, 5, .93);
    -webkit-backdrop-filter: blur(22px) saturate(1.1);
    backdrop-filter: blur(22px) saturate(1.1);
    direction: rtl;
    font-family: Shabnam, Tahoma, sans-serif;
}

/* FOUR rows for four children: bars, top, stage, foot. This said `auto 1fr auto`,
   which handed the 1fr to the handle strip and left the stage as an implicit auto
   row — the stage collapsed, its frame had no height to fill, and every frame
   rendered at max-width and overflowed. The stage is the only row that should grow. */
.vb-ig-lb.is-open { display: grid; grid-template-rows: auto auto 1fr auto; }
body.vb-ig-lock { overflow: hidden; }

.vb-ig-lb__bars {
    display: flex;
    gap: 4px;
    padding: 1rem clamp(1rem, 4vw, 2rem) .5rem;
}

.vb-ig-lb__bar {
    flex: 1 1 0;
    height: 2.5px;
    border-radius: 2px;
    background: rgba(255, 255, 255, .2);
    overflow: hidden;
}

.vb-ig-lb__fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 2px;
    background: var(--vb-ig-brass-lit, #F0C078);
}

.vb-ig-lb__bar.is-done .vb-ig-lb__fill { width: 100%; }

.vb-ig-lb__top {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: 0 clamp(1rem, 4vw, 2rem) .75rem;
}

.vb-ig-lb__top img {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid rgba(240, 192, 120, .5);
}

/* unicode-bidi:plaintext — NOT direction:ltr. Both render the Latin handle
   left-to-right, but `direction` also re-resolves logical properties against
   the element's own axis, which flipped margin-inline-end to the right and
   parked the handle next to the close button instead of the avatar. plaintext
   picks the run direction from the first strong character and leaves the box
   logically RTL, so the auto margin still pushes the close button left. */
.vb-ig-lb__who {
    unicode-bidi: plaintext;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .68rem;
    color: rgba(255, 255, 255, .82);
    margin-inline-end: auto;
}

.vb-ig-lb__x {
    background: none;
    border: 0;
    padding: .4rem;
    cursor: pointer;
    color: rgba(255, 255, 255, .82);
    border-radius: 50%;
    line-height: 0;
}

.vb-ig-lb__x:hover { color: #fff; background: rgba(255, 255, 255, .1); }
.vb-ig-lb__x svg { width: 1.35rem; height: 1.35rem; }

/* The stage takes its height from the 1fr row of .vb-ig-lb; the frame is then
   absolutely positioned to fill it. That indirection is load-bearing: laying the
   frame out as a centred grid ITEM made its row content-sized, so `height:100%`
   on the frame was indefinite, the image's `max-height:100%` resolved against
   nothing and was dropped, and a square frame rendered at 156% of the stage and
   got clipped. An absolute box has a definite height, so max-height works. */
.vb-ig-lb__stage {
    position: relative;
    min-height: 0;
    overflow: hidden;
}

/* A 4:5 frame leaves most of a desktop viewport empty. Rather than fill it with
   chrome, the frame's own photograph is blown up and blurred behind it — the
   colour in the room comes from the image being viewed. Costs no extra request
   (same src, already decoded) and disappears on phones, where the frame fills
   the screen and there is nothing to fill. */
.vb-ig-lb__glow {
    position: absolute;
    inset: -12%;
    width: 124%;
    height: 124%;
    object-fit: cover;
    filter: blur(72px) saturate(1.5) brightness(.55);
    opacity: 0;
    transition: opacity .7s ease;
    z-index: 0;
    pointer-events: none;
}

.vb-ig-lb__glow.is-live { opacity: .55; }

@media (max-width: 700px) {
    .vb-ig-lb__glow { display: none; }
}

/* The image sizes itself; the frame is only a centring context.
   A fixed portrait box letterboxed the landscape frames down to a stamp — the
   set runs 0.75 to 1.78 aspect, so any single box shape is wrong for most of it.
   With max-width + max-height and natural width/height, every frame fills as
   much of the stage as its own shape allows, with zero letterboxing. */
/* FLEX, not grid. `place-items:center` on a grid makes the track content-sized,
   which leaves the image's `max-height:100%` resolving against an indefinite
   height — so it was silently dropped and every frame overflowed at max-width.
   A flex item's percentage max-height resolves against the flex container's
   definite content box, which `inset:0` guarantees. */
.vb-ig-lb__frame {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 clamp(.5rem, 3vw, 2rem);
}

.vb-ig-lb__frame img {
    max-width: min(100%, 68rem);
    max-height: 100%;
    width: auto;
    height: auto;
    display: block;
    border-radius: 14px;
    box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .9), 0 0 0 1px rgba(255, 255, 255, .07);
}

/* Ken Burns rides the blurred backdrop, not the photograph. Zooming the frame
   itself would crop the work being shown — the whole point is to see it whole. */
.vb-ig-lb__glow.is-live { animation: vb-ig-kb 6s ease-out both; }

@keyframes vb-ig-kb {
    from { transform: scale(1); }
    to   { transform: scale(1.1); }
}

/* Tap zones. RTL: the LEFT half advances, because the on-screen "next"
   direction in a right-to-left reading order points left. */
.vb-ig-lb__zone {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 42%;
    z-index: 3;
    border: 0;
    background: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.vb-ig-lb__zone--next { left: 0; }
.vb-ig-lb__zone--prev { right: 0; }
.vb-ig-lb__zone:focus-visible { outline: 2px solid var(--ig-brass-lit); outline-offset: -6px; }

.vb-ig-lb__foot {
    padding: .9rem clamp(1rem, 4vw, 2rem) clamp(1rem, 4vw, 1.75rem);
    max-width: 34rem;
    margin: 0 auto;
    width: 100%;
    text-align: center;
}

.vb-ig-lb__text {
    font-size: clamp(.82rem, 2.2vw, .95rem);
    line-height: 1.9;
    color: var(--ig-bone, #EFEAE2);
    margin: 0 0 .75rem;
}

.vb-ig-lb__out {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    font-size: .78rem;
    font-weight: 700;
    color: #F0C078;
    text-decoration: none;
    border-bottom: 1px solid rgba(240, 192, 120, .35);
    padding-bottom: 2px;
}

.vb-ig-lb__out:hover { color: #fff; border-color: #fff; }
.vb-ig-lb__out svg { width: .85rem; height: .85rem; }

/* ---------- responsive ---------- */

@media (max-width: 860px) {
    .vb-ig { --ig-row: 11rem; }
    .vb-ig__head { flex-wrap: wrap; }
    .vb-ig__follow { order: 3; width: 100%; justify-content: center; }
}

@media (max-width: 460px) {
    .vb-ig { --ig-row: 9.5rem; }
}

/* On a phone the viewer's chrome is competing with the photograph for a very
   short stage, so give the frame back every pixel the header and footer can spare. */
@media (max-width: 700px) {
    .vb-ig-lb__bars { padding: .55rem .7rem .35rem; gap: 3px; }
    .vb-ig-lb__top { padding: 0 .7rem .5rem; }
    .vb-ig-lb__top img { width: 1.75rem; height: 1.75rem; }
    .vb-ig-lb__frame { padding: 0 .4rem; }
    .vb-ig-lb__frame img { border-radius: 10px; }
    .vb-ig-lb__foot { padding: .7rem .9rem 1.1rem; }
    .vb-ig-lb__text {
        margin-bottom: .5rem;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    /* Wider tap targets: on a phone the zones are the primary navigation. */
    .vb-ig-lb__zone { width: 48%; }
}

/* ---------- reduced motion ----------
   Drift, pulse, Ken Burns and auto-advance all stop. The rail stays swipeable
   and the viewer stays keyboard/tap navigable — nothing is lost but movement.
   (JS reads the same query to disable the timer.) */
@media (prefers-reduced-motion: reduce) {
    .vb-ig *,
    .vb-ig-lb * {
        animation: none !important;
        transition-duration: .01ms !important;
    }
    .vb-ig__card:hover { transform: none; }
    .vb-ig__card:hover img { transform: none; }
}
