/* ==========================================================================
   MAGNETIQ V2 : work.css
   Page stylesheet for work.html. Loads AFTER core.css and only adds what is
   genuinely specific to the work page: the hero, the filter rail, the project
   grid, the case modal, the pinned proof band and the closing CTA.

   Nothing declared in core.css is redefined here.

   CONTENTS
     01  Hero
     02  Filter rail
     03  Project grid
     04  Case modal
     05  Pinned proof band
     06  Marquee strip
     07  Closing CTA
   ========================================================================== */


/* ==========================================================================
   01  HERO
   Rather than data-bleed (which is fully transparent and therefore depends on
   <html> already carrying the dark surface) the hero paints its own nearly
   opaque ink. The liquid ink object still glows through the last few percent,
   and the copy stays readable even if the motion engine never boots.
   ========================================================================== */

/* The hero lets the object through completely, the same treatment studio.html uses.
   An 87% ink veil used to sit here, which crushed the object's saturated mid tones
   into an olive smudge and left a hard horizontal seam where the next section went
   opaque. Full transparency reads as intended chrome; the copy column sits left of
   the object and the side paragraph clears its lower edge. */
.wk-hero{
  background:transparent;
  min-height:clamp(560px,92svh,1040px);
  display:flex;
  align-items:flex-end;
  padding-top:calc(var(--hdr-h) + clamp(36px,7vh,90px));
  padding-bottom:clamp(48px,8vh,110px);
  overflow:hidden;
}
.wk-hero > .wrap{ width:100%; }

.wk-hero-in{
  display:grid;
  gap:clamp(26px,4vw,60px);
}
@media (min-width:960px){
  .wk-hero-in{
    grid-template-columns:minmax(0,1.4fr) minmax(0,.8fr);
    align-items:end;
    column-gap:clamp(40px,6vw,110px);
  }
}

.wk-hero h1{ margin-top:clamp(16px,2.4vh,30px); }

.wk-hero-side{
  display:flex;
  flex-direction:column;
  gap:clamp(16px,2.4vh,26px);
  padding-bottom:.6em;
}
.wk-hero-side p{ max-width:40ch; margin:0; }

.wk-hero-meta{
  display:flex;
  flex-wrap:wrap;
  gap:10px 22px;
  padding-top:clamp(14px,2vh,20px);
  border-top:1px solid var(--line);
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--fg-dim);
}
.wk-hero-meta b{
  color:var(--fg);
  font-weight:500;
  font-variant-numeric:tabular-nums;
}

.wk-cue{
  display:inline-flex;
  flex-direction:column;
  align-items:flex-start;
  gap:12px;
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--fg-dim);
  margin-top:clamp(28px,5vh,56px);
}
.wk-cue i{
  display:block;
  width:1px;
  height:40px;
  background:linear-gradient(180deg,currentColor,transparent);
  animation:wkCue 2.4s var(--e-io) infinite;
  transform-origin:0 0;
}
@keyframes wkCue{
  0%   { transform:scaleY(.2); opacity:.2; }
  45%  { transform:scaleY(1);  opacity:1; }
  100% { transform:scaleY(.2); opacity:.2; }
}


/* ==========================================================================
   02  FILTER RAIL
   ========================================================================== */

.flt{
  display:flex;
  align-items:center;
  gap:14px 20px;
  flex-wrap:wrap;
  padding-block:clamp(12px,1.6vh,18px);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  margin-bottom:clamp(30px,5vh,60px);
}

.flt-list{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  margin-right:auto;
  min-width:0;
}

.flt-btn{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  line-height:1;
  padding:10px 15px;
  border-radius:999px;
  border:1px solid var(--line);
  color:var(--fg-dim);
  white-space:nowrap;
  transition:color .32s var(--e-out), border-color .32s var(--e-out),
             background-color .32s var(--e-out);
}
.flt-btn:hover{ color:var(--fg); border-color:color-mix(in srgb,var(--fg) 42%,transparent); }
.flt-btn[aria-pressed="true"]{
  color:var(--bg);
  background:var(--fg);
  border-color:var(--fg);
}

.flt-count{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--fg-dim);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.flt-count b{ color:var(--fg); font-weight:500; }

@media (max-width:520px){
  .flt{ gap:12px; }
  .flt-list{ margin-right:0; width:100%; }
  .flt-count{ width:100%; }
}


/* ==========================================================================
   03  PROJECT GRID
   ========================================================================== */

.wk-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(30px,3.4vw,54px) clamp(20px,2.2vw,34px);
  align-content:start;
}
@media (max-width:1080px){ .wk-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:620px){  .wk-grid{ grid-template-columns:minmax(0,1fr); } }

.wk-item{ min-width:0; }
.wk-item.is-out{ display:none; }
/* Added only for the duration of a FLIP move, so it never fights the reveal. */
.wk-item.is-flip{
  transition:transform .58s var(--e-out), opacity .45s var(--e-out);
  will-change:transform;
}

.wk-card{
  display:block;
  width:100%;
  padding:0;
  text-align:left;
  background:none;
  border:0;
  color:inherit;
  /* [data-tilt] writes the inline transform on this element, so it must never
     carry a transform of its own. */
}
.wk-card:focus-visible{ outline:2px solid var(--volt); outline-offset:6px; border-radius:calc(var(--r) + 4px); }

.wk-frame{
  position:relative;
  display:block;
  border-radius:var(--r);
  overflow:hidden;
  background:var(--faint);
  border:1px solid var(--line);
  transition:border-color .45s var(--e-out), box-shadow .55s var(--e-out);
}
.wk-frame img{
  width:100%;
  height:auto;
  aspect-ratio:16 / 10;
  object-fit:cover;
}
.wk-frame::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  background:linear-gradient(180deg,rgba(10,10,12,0) 38%,rgba(10,10,12,.78) 100%);
  opacity:0;
  transition:opacity .5s var(--e-out);
  pointer-events:none;
}
.wk-card:hover .wk-frame,
.wk-card:focus-visible .wk-frame{
  border-color:color-mix(in srgb,var(--fg) 38%,transparent);
  box-shadow:0 26px 60px rgba(10,10,12,.22);
}
.wk-card:hover .wk-frame::after,
.wk-card:focus-visible .wk-frame::after{ opacity:1; }

.wk-idx{
  position:absolute;
  top:13px;
  left:15px;
  z-index:2;
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.18em;
  color:#EDE8DE;
  text-shadow:0 1px 8px rgba(10,10,12,.65);
  font-variant-numeric:tabular-nums;
}

.wk-over{
  position:absolute;
  left:0; right:0; bottom:0;
  z-index:2;
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:14px;
  padding:16px 18px;
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:#EDE8DE;
  opacity:0;
  transform:translateY(12px);
  transition:opacity .45s var(--e-out), transform .55s var(--e-out);
  pointer-events:none;
}
.wk-over em{ font-style:normal; opacity:.7; font-variant-numeric:tabular-nums; }
.wk-card:hover .wk-over,
.wk-card:focus-visible .wk-over{ opacity:1; transform:none; }

.wk-meta{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:14px;
  margin-top:clamp(13px,1.6vh,18px);
}
.wk-name{
  font-family:var(--display);
  font-weight:500;
  font-variation-settings:'opsz' 32,'wght' 500;
  font-size:clamp(1.05rem,1.5vw,1.35rem);
  letter-spacing:-.025em;
  line-height:1.1;
  color:var(--fg);
}
.wk-sub{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--fg-dim);
  text-align:right;
}
.wk-tags{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
  margin-top:11px;
}

/* Touch and coarse pointers never get a hover, so the overlay rides along with
   the card at all times instead of hiding information. */
@media (hover:none){
  .wk-over{ opacity:1; transform:none; }
  .wk-frame::after{ opacity:1; }
}


/* ==========================================================================
   04  CASE MODAL
   Lives outside #smooth at body level, so it stays fixed while the motion
   engine transforms the scroll content.
   ========================================================================== */

.case{
  position:fixed;
  inset:0;
  z-index:9500;
  display:flex;
  align-items:flex-end;
  justify-content:center;
  visibility:hidden;
  pointer-events:none;
}
.case.is-open{ visibility:visible; pointer-events:auto; }

.case-scrim{
  position:absolute;
  inset:0;
  background:rgba(10,10,12,.74);
  -webkit-backdrop-filter:blur(7px);
  backdrop-filter:blur(7px);
  opacity:0;
  transition:opacity .5s var(--e-out);
  cursor:pointer;
}
.case.is-open .case-scrim{ opacity:1; }

.case-panel{
  position:relative;
  z-index:2;
  width:min(1120px,100%);
  max-height:min(94svh,1040px);
  display:flex;
  flex-direction:column;
  border-radius:var(--r-lg) var(--r-lg) 0 0;
  overflow:hidden;
  transform:translateY(100%);
  transition:transform .78s var(--e-io);
  will-change:transform;
  /* The panel takes focus on open so screen readers announce the dialog. It is
     a container, not a control, so it must not paint a focus ring. */
  outline:none;
  /* The panel is its own ink surface, whatever the page behind it is doing. */
  background:var(--ink);
  color:var(--bone);
  --bg:#0A0A0C;
  --fg:#EDE8DE;
  --fg-dim:#8C8C99;
  --line:rgba(237,232,222,.14);
  --faint:rgba(237,232,222,.05);
  --card:#131318;
  box-shadow:0 -30px 90px rgba(0,0,0,.5);
}
.case.is-open .case-panel{ transform:none; }

.case-bar{
  flex:none;
  display:flex;
  align-items:center;
  gap:14px;
  padding:16px clamp(18px,3vw,40px);
  border-bottom:1px solid var(--line);
  background:var(--ink);
}
.case-idx{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.2em;
  color:var(--fg-dim);
  font-variant-numeric:tabular-nums;
}
.case-name{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--fg);
  margin-right:auto;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.case-x{
  flex:none;
  position:relative;
  width:42px; height:42px;
  border-radius:50%;
  border:1px solid var(--line);
  color:var(--fg);
  transition:border-color .35s var(--e-out), transform .45s var(--e-spring);
}
.case-x span{
  position:absolute;
  left:50%; top:50%;
  width:15px; height:1.5px;
  background:currentColor;
  border-radius:2px;
}
.case-x span:nth-child(1){ transform:translate(-50%,-50%) rotate(45deg); }
.case-x span:nth-child(2){ transform:translate(-50%,-50%) rotate(-45deg); }
.case-x:hover{ border-color:currentColor; transform:rotate(90deg); }

.case-scroll{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  padding:clamp(20px,3.2vw,44px) clamp(18px,3vw,40px) clamp(30px,5vh,60px);
}

.case-story{ display:flex; flex-direction:column; gap:clamp(22px,3vh,38px); }
.case-story[hidden]{ display:none; }

/* Entry stagger for the open panel. Reduced motion collapses the durations in
   core.css, and the end state is the visible one, so nothing can be stranded. */
.case-story > *{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .7s var(--e-out), transform .85s var(--e-out);
}
.case.is-open .case-story > *{ opacity:1; transform:none; }
.case.is-open .case-story > *:nth-child(1){ transition-delay:.16s; }
.case.is-open .case-story > *:nth-child(2){ transition-delay:.24s; }
.case.is-open .case-story > *:nth-child(3){ transition-delay:.32s; }
.case.is-open .case-story > *:nth-child(4){ transition-delay:.40s; }
.case.is-open .case-story > *:nth-child(5){ transition-delay:.48s; }

.case-shot{
  position:relative;
  width:100%;
  border-radius:var(--r);
  overflow:hidden;
  border:1px solid var(--line);
  background:var(--faint);
}
/* Capped, not free running: the story has to be readable the moment the panel
   lands, so the shot never eats the whole first screen. */
.case-shot img{
  width:100%;
  height:clamp(180px,34svh,360px);
  object-fit:cover;
  object-position:50% 20%;
}

.case-head{ display:flex; flex-direction:column; gap:16px; }
.case-h{
  font-family:var(--display);
  font-weight:500;
  font-variation-settings:'opsz' 72,'wght' 500;
  font-size:clamp(2rem,5vw,3.6rem);
  letter-spacing:-.035em;
  line-height:.96;
  color:var(--fg);
}
.case-lede{
  font-family:var(--body);
  font-size:clamp(16px,1.4vw,20px);
  line-height:1.5;
  letter-spacing:-.01em;
  color:var(--fg);
  max-width:56ch;
}
.case-tags{ --gap:7px; }

.case-grid{
  display:grid;
  gap:clamp(20px,2.4vw,36px);
  padding-top:clamp(20px,3vh,32px);
  border-top:1px solid var(--line);
}
@media (min-width:820px){
  .case-grid{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}
.case-block h6{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.18em;
  text-transform:uppercase;
  font-weight:500;
  font-variation-settings:'wght' 500;
  color:var(--fg-dim);
  margin-bottom:12px;
}
.case-block p{ max-width:44ch; font-size:15px; }

.case-stats{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,2vw,28px);
  padding-block:clamp(20px,3vh,32px);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
@media (max-width:560px){
  .case-stats{ grid-template-columns:minmax(0,1fr); gap:18px; }
}
.case-stat{ display:flex; flex-direction:column; gap:8px; min-width:0; }
.case-stat .num{
  font-size:clamp(1.9rem,3.6vw,3rem);
  line-height:.92;
}
.case-stat span:last-child{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--fg-dim);
}

.case-cta{
  display:flex;
  flex-wrap:wrap;
  gap:12px;
  align-items:center;
}
.case-cta .btn{ flex:0 1 auto; }
@media (max-width:460px){
  .case-cta .btn{ flex:1 1 100%; }
}

/* The floating WhatsApp bubble steps aside for the panel, exactly as it does
   for the drawer. */
html.is-case .wa-bubble{
  opacity:0;
  transform:scale(.82) translateY(10px);
  pointer-events:none;
}

@media (min-width:900px){
  .case{ align-items:center; padding:clamp(20px,4vh,48px) var(--gut); }
  .case-panel{ border-radius:var(--r-lg); max-height:min(88svh,980px); }
}


/* ==========================================================================
   05  PINNED PROOF BAND
   The scroll scrubs three statements. Everything is driven from --p, which
   motion.js writes on the [data-pin] host, so there is no per frame JS.
   ========================================================================== */

.pf{
  padding-block:0;
  /* Fully opaque on purpose. This band centres its copy over the full width, so the
     object is not allowed to sit behind it. An 84% veil used to let just enough of
     the object through to read as a stain rather than a shape, and the step up to
     the opaque band below it showed as a hard horizontal seam. The object gets the
     hero, this band gets the words. */
  background:var(--ink);
}

.pf-pin{ position:relative; }

.pin-inner.pf-inner{
  min-height:100svh;
  display:flex;
  align-items:center;
  padding-block:clamp(80px,12vh,140px);
}
.pf-inner > .wrap{ width:100%; }

.pf-top{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:18px;
  flex-wrap:wrap;
  margin-bottom:clamp(30px,6vh,70px);
}
.pf-dots{ display:flex; gap:8px; }
.pf-dots i{
  width:22px; height:2px;
  background:var(--fg);
  opacity:.18;
  display:block;
  transition:opacity .4s var(--e-out);
}
.pf-dots i:nth-child(1){ opacity:clamp(.18,calc((.30 - var(--p,0)) * 16),1); }
.pf-dots i:nth-child(2){ opacity:clamp(.18,calc(min((var(--p,0) - .30) * 16,(.66 - var(--p,0)) * 16)),1); }
.pf-dots i:nth-child(3){ opacity:clamp(.18,calc((var(--p,0) - .66) * 16),1); }

.pf-stage{
  display:grid;
  /* A masked window, same conveyor as the home why-lines: statements leave
     through the top and arrive through the bottom, always one window apart,
     so the stage is never empty and two statements never stack. */
  overflow:hidden;
  padding-block:.1em;
}
.pf-item{
  grid-area:1 / 1;
  display:flex;
  flex-direction:column;
  gap:clamp(16px,2.4vh,26px);
  will-change:opacity,transform;
}
.pf-item .num{ font-size:clamp(3.4rem,13vw,11rem); }
.pf-item p{ max-width:46ch; font-size:clamp(16px,1.5vw,21px); line-height:1.5; color:var(--fg); }

/* On a wide screen the statement fills the band instead of hugging the left
   gutter: number on one side, sentence on the other. */
@media (min-width:900px){
  .pf-item{
    display:grid;
    grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
    align-items:center;
    column-gap:clamp(30px,6vw,110px);
  }
  .pf-item .num{ font-size:clamp(3.4rem,9vw,8.4rem); }
  .pf-item p{ max-width:36ch; }
}

/* The three statements share one grid cell, so their fades are butt joined
   rather than overlapped: the outgoing line is fully out at the exact point
   the incoming one starts. An overlapping crossfade double exposed two
   headlines and two paragraphs on top of each other for a readable beat. */
.pf-item:nth-child(1){
  --a:1;
  --b:clamp(0,calc((var(--p,0) - .30) * 16),1);
  opacity:1;
  transform:translate3d(0,calc((1 - var(--a) - var(--b)) * 100%),0);
}
.pf-item:nth-child(2){
  --a:clamp(0,calc((var(--p,0) - .30) * 16),1);
  --b:clamp(0,calc((var(--p,0) - .66) * 16),1);
  opacity:1;
  transform:translate3d(0,calc((1 - var(--a) - var(--b)) * 100%),0);
}
.pf-item:nth-child(3){
  --a:clamp(0,calc((var(--p,0) - .66) * 16),1);
  --b:0;
  opacity:1;
  transform:translate3d(0,calc((1 - var(--a) - var(--b)) * 100%),0);
}

.pf-rail{
  position:relative;
  width:100%;
  height:2px;
  background:var(--line);
  margin-top:clamp(36px,7vh,80px);
  overflow:hidden;
}
.pf-rail > i{
  position:absolute;
  inset:0;
  display:block;
  background:var(--iris);
  background-size:220% 100%;
  background-position:0% 50%;
  transform:scaleX(var(--p,0));
  transform-origin:0 50%;
}

/* Without the pin (reduced motion) the three statements would stack on top of
   each other, so they fall back to a readable column. */
@media (prefers-reduced-motion: reduce){
  .pin-inner.pf-inner{ min-height:0; }
  .pf-stage{ gap:clamp(30px,6vh,64px); }
  .pf-item{ grid-area:auto; opacity:1 !important; transform:none !important; }
  .pf-dots i{ opacity:.5 !important; }
  .pf-rail > i{ transform:scaleX(1); }
}


/* ==========================================================================
   06  MARQUEE STRIP
   ========================================================================== */

.wk-mq{ padding-block:clamp(40px,7vh,90px); }
.wk-mq .marquee{ border-top:1px solid var(--line); border-bottom:1px solid var(--line); padding-block:clamp(20px,3vh,34px); }
.wk-mq .marquee-item{ color:var(--fg); }
.wk-mq .marquee-item.is-dim{ color:var(--fg-dim); }


/* ==========================================================================
   07  CLOSING CTA
   ========================================================================== */

.wk-cta{ text-align:center; }
.wk-cta .kicker{ justify-content:center; }
.wk-cta h2{ margin-top:clamp(16px,2.4vh,28px); }
.wk-cta p{ margin-inline:auto; max-width:48ch; }
.wk-cta .cluster{ justify-content:center; margin-top:clamp(26px,4vh,44px); }
.wk-cta-note{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--fg-dim);
  margin-top:clamp(20px,3vh,32px);
}


/* ==========================================================================
   LIVE PREVIEW (preview.js)
   The case screenshot doubles as the poster for a real, running copy of the
   site at /demo/<slug>/. Nothing here loads until the visitor presses play.
   ========================================================================== */

.case-shot{ position:relative; }

/* while a preview is open the site's own 3D canvas is hidden, which makes its
   IntersectionObserver stop the render loop, so only one WebGL scene runs */
html.pv-on #gl{ display:none; }

/* ---- the play button over the poster ---- */
.pv-play{
  position:absolute;
  left:50%; top:50%;
  transform:translate(-50%,-50%);
  display:inline-flex; align-items:center; gap:12px;
  padding:14px 22px 14px 18px;
  border:1px solid color-mix(in srgb, var(--chalk) 34%, transparent);
  border-radius:999px;
  background:color-mix(in srgb, var(--ink) 62%, transparent);
  backdrop-filter:blur(16px) saturate(1.3);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);
  color:var(--chalk);
  font-family:var(--mono);
  font-size:11px; letter-spacing:.16em; text-transform:uppercase;
  cursor:pointer;
  transition:background .3s var(--e-out), border-color .3s var(--e-out), transform .4s var(--e-spring);
}
.pv-play:hover{
  background:color-mix(in srgb, var(--ink) 78%, transparent);
  border-color:var(--chalk);
  transform:translate(-50%,-50%) scale(1.04);
}
.pv-play-ico{
  width:26px; height:26px; flex:none;
  border-radius:50%;
  background:var(--iris);
  position:relative;
}
.pv-play-ico::after{
  content:""; position:absolute;
  left:52%; top:50%; transform:translate(-50%,-50%);
  border-style:solid;
  border-width:5px 0 5px 8px;
  border-color:transparent transparent transparent #0A0A0C;
}
.case-shot.is-live .pv-play{ display:none; }

.pv-note{
  position:absolute; left:0; right:0; bottom:10px;
  margin:0; padding:0 16px;
  text-align:center;
  font-family:var(--mono);
  font-size:9.5px; letter-spacing:.12em; text-transform:uppercase;
  color:color-mix(in srgb, var(--chalk) 62%, transparent);
  text-shadow:0 1px 6px rgba(0,0,0,.6);
  pointer-events:none;
}
.case-shot.is-live .pv-note{ display:none; }

/* ---- the mock browser ---- */
.pv-frame{
  position:absolute; inset:0;
  display:flex; flex-direction:column;
  border-radius:inherit;
  overflow:hidden;
  background:var(--ink-2);
  animation:pvIn .5s var(--e-out) both;
}
@keyframes pvIn{ from{ opacity:0; transform:scale(.985); } to{ opacity:1; transform:none; } }

.pv-bar{
  flex:none;
  display:flex; align-items:center; gap:14px;
  padding:9px 12px;
  background:var(--ink-3);
  border-bottom:1px solid rgba(255,255,255,.08);
}
.pv-dots{ display:inline-flex; gap:6px; flex:none; }
.pv-dots i{ width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.22); }
.pv-dots i:first-child{ background:#FF5F57; }
.pv-dots i:nth-child(2){ background:#FEBC2E; }
.pv-dots i:nth-child(3){ background:#28C840; }

.pv-url{
  flex:1 1 auto;
  min-width:0;
  padding:5px 14px;
  border-radius:999px;
  background:rgba(255,255,255,.07);
  color:color-mix(in srgb, var(--bone) 72%, transparent);
  font-family:var(--mono);
  font-size:11px; letter-spacing:.06em;
  text-align:center;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.pv-acts{ display:inline-flex; gap:8px; flex:none; }
.pv-tab, .pv-close{
  border:1px solid rgba(255,255,255,.16);
  background:transparent;
  border-radius:999px;
  padding:5px 12px;
  color:color-mix(in srgb, var(--bone) 82%, transparent);
  font-family:var(--mono);
  font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
  cursor:pointer; text-decoration:none;
  transition:color .25s, border-color .25s, background .25s;
}
.pv-tab:hover, .pv-close:hover{ color:#fff; border-color:#fff; background:rgba(255,255,255,.08); }

/* The poster is a short banner crop, which is right for a screenshot and wrong
   for a running site. While live, the shot grows to a real viewport shape. */
.case-shot.is-live{ height:min(64vh, 660px); }
.case-shot.is-live img{ visibility:hidden; }

.pv-stage{ position:relative; flex:1 1 auto; overflow:hidden; background:var(--ink); }

/* The iframe is rendered at a genuine desktop width and then scaled down, so
   the site inside lays itself out exactly as it would on a real monitor. Give
   it the box width instead and every one of these sites would reflow to its
   tablet or mobile breakpoint, which is not what a client is asking to see. */
.pv-iframe{
  position:absolute; top:0; left:0;
  width:var(--pv-w, 1440px);
  height:var(--pv-h, 900px);
  transform:scale(var(--pv-s, 1));
  transform-origin:0 0;
  border:0;
  opacity:0;
  transition:opacity .6s var(--e-out);
}
.pv-frame.is-ready .pv-iframe{ opacity:1; }

.pv-load{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
  color:color-mix(in srgb, var(--bone) 70%, transparent);
  font-family:var(--mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase;
}
.pv-load i{
  width:26px; height:26px;
  border-radius:50%;
  border:2px solid rgba(255,255,255,.14);
  border-top-color:var(--volt-2);
  animation:pvSpin .9s linear infinite;
}
@keyframes pvSpin{ to{ transform:rotate(360deg); } }
.pv-frame.is-ready .pv-load{ opacity:0; pointer-events:none; transition:opacity .4s; }

/* Small screens never embed: the button opens the real site in a new tab, so
   the mock browser and its chrome are not needed at all. */
@media (max-width:899px){
  .pv-frame{ display:none; }
  .pv-play{ font-size:10px; padding:12px 18px 12px 14px; }
}

@media (prefers-reduced-motion: reduce){
  .pv-frame{ animation:none; }
  .pv-load i{ animation:none; }
  .pv-play{ transition:none; }
  .pv-play:hover{ transform:translate(-50%,-50%); }
}
