/* ═══════════════════════════════════════════════════════════
   D.E. VISUALS: werk.devisuals.studio
   Unlisted one-page pitch surface. It is the devisuals.studio
   skin, not a cousin: the @font-face block and the :root token
   block below are copied verbatim from site/style.css, and the
   motion vocabulary (.rise, .rv, --eo/--eio/--ed, the pinned
   stage) is the site's own. Nothing here is invented, and
   site/ is never written to.
   ═══════════════════════════════════════════════════════════ */

/* ═══════════ TYPE: verbatim from site/style.css ═══════════
   Self-hosted, latin subset, no third-party requests. Archivo and Inter ship as
   variable files (Archivo keeps its wdth axis). The *Fallback faces are the local
   system faces with metric overrides computed against Arial/Courier New, so a swap
   costs zero layout shift. Google Fonts is never contacted. */
@font-face{font-family:'Archivo';font-style:normal;font-weight:400 900;
  font-stretch:62% 125%;font-display:swap;
  src:url('fonts/archivo-var-latin.woff2') format('woff2')}
@font-face{font-family:'Archivo Fallback';src:local('Arial'),local('Helvetica Neue'),local('Helvetica');
  size-adjust:91.40%;ascent-override:96.06%;descent-override:22.98%;line-gap-override:0%}

@font-face{font-family:'Inter';font-style:normal;font-weight:400 500;font-display:swap;
  src:url('fonts/inter-var-latin.woff2') format('woff2')}
@font-face{font-family:'Inter Fallback';src:local('Arial'),local('Helvetica Neue'),local('Helvetica');
  size-adjust:95.67%;ascent-override:101.26%;descent-override:25.21%;line-gap-override:0%}

@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/plexmono-400-latin.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/plexmono-500-latin.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono Fallback';src:local('Courier New'),local('Menlo');
  size-adjust:100%;ascent-override:102.50%;descent-override:27.50%;line-gap-override:0%}

/* ═══════════ TOKENS: verbatim from site/style.css ═══════════ */
:root{
  --void:#070706; --bone:#F2F0EA; --muted:#8C8A83; --dim:#7A7873; --signal:#E42922;
  --disp:'Archivo','Archivo Fallback','Helvetica Neue',Arial,sans-serif;
  --body:'Inter','Inter Fallback','Helvetica Neue',Arial,sans-serif;
  --mono:'IBM Plex Mono','IBM Plex Mono Fallback',ui-monospace,monospace;
  --edge:1.75vw;
  --l2:25.875vw;
  --l3:50vw;
  --l4:74.125vw;
  --h1:clamp(34px,min(3.62vw,8.6vh),124px);
  --h2:clamp(26px,min(3.05vw,5.4vh),68px);
  --lbl:clamp(9px,min(.68vw,1.2vh),13px);
  --txt:clamp(13px,min(.95vw,1.7vh),18px);
  --rule:rgba(242,240,234,.13);
  --sec:clamp(72px,11vh,168px);
  /* strong custom curves: default CSS easings are too weak */
  --eo:cubic-bezier(.16,1,.3,1);      /* confident arrival: entrances, hovers */
  --eio:cubic-bezier(.77,0,.175,1);   /* on-screen movement, reveals          */
  --ed:cubic-bezier(.32,.72,0,1);     /* drawers, sheets, menu panel (iOS)    */
}
/* Landing-only: --edge is a grid-line unit and collapses to 5.6px at 320px wide.
   Content padding gets its own floor so nothing ever touches the screen edge. */
:root{ --pad:clamp(18px,1.75vw,40px); --hdh:clamp(54px,7.4vh,84px); }

*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{background:var(--void);color:var(--bone);font-family:var(--body);
  font-size:var(--txt);line-height:1.62;overflow-x:clip;
  -webkit-font-smoothing:antialiased;position:relative}
a{color:inherit;text-decoration:none;text-underline-offset:.22em;text-decoration-thickness:1px}
img,video{display:block;max-width:100%}
::selection{background:var(--signal);color:var(--bone)}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
h1,h2,h3{font-family:var(--disp);font-weight:700;text-transform:uppercase;
  letter-spacing:-.005em;line-height:.98}
.vh{position:absolute!important;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:fixed;top:0;left:0;z-index:100;transform:translateY(-130%);
  background:var(--signal);color:#fff;padding:12px 18px;font-family:var(--mono);
  font-size:var(--lbl);letter-spacing:.16em;text-transform:uppercase;
  transition:transform .25s var(--eo)}
.skip:focus,.skip:focus-visible{transform:translateY(0)}

/* Lenis base: eased native scroll, not hijacked scrolling, so position:sticky,
   the scroll-driven stage animation and anchors all keep working. */
html.lenis,html.lenis body{height:auto}
.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}
.lenis [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-smooth iframe{pointer-events:none}

/* ═══════════ the four vertical grid rules, behind everything ═══════════ */
.grid{position:fixed;inset:0;z-index:0;pointer-events:none}
.grid i{position:absolute;top:0;bottom:0;width:1px;background:var(--rule)}
@media(max-width:900px){.grid{display:none}}

/* ═══════════ HEADER ═══════════
   No tabs: this page is one page, and a tab pointing at a page that does not
   exist yet is the exact failure the skill records. Logo and language only. */
.hd{position:fixed;top:0;left:0;right:0;z-index:40;
  display:flex;align-items:center;justify-content:space-between;
  padding:clamp(12px,1.6vh,22px) var(--pad);
  transition:background .4s var(--eo),backdrop-filter .4s var(--eo),
    border-color .4s var(--eo);border-bottom:1px solid transparent}
.hd.stuck{background:rgba(7,7,6,.72);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);border-bottom-color:var(--rule)}
.hd img{height:clamp(26px,3.4vh,38px);width:auto}
.lang{display:flex;align-items:center;font-family:var(--mono);font-size:var(--lbl);
  letter-spacing:.14em;gap:.35em}
.lang button{background:none;border:0;color:var(--dim);cursor:pointer;
  font:inherit;padding:6px 4px;transition:color .25s ease}
.lang button.on{color:var(--bone)}
.lang button:hover{color:var(--bone)}
.lang em{color:var(--dim);font-style:normal}

/* ═══════════ THE STAGE: the holding page's treatment, pinned ═══════════
   Sticky, not static: main scrolls OVER it. That overlap is the parallax. */
.stage{position:sticky;top:0;height:100svh;min-height:540px;overflow:clip;z-index:1}
.bg{position:absolute;inset:0;z-index:0;overflow:clip;background:var(--void)}
.poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.reel{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity 1.4s ease;z-index:1}
.reel.on{opacity:1}
.side{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to right,
    rgba(7,7,6,.93) 0%, rgba(7,7,6,.80) 24%, rgba(7,7,6,.46) 47%,
    rgba(7,7,6,.16) 70%, rgba(7,7,6,.06) 100%)}
.fall{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(7,7,6,.58) 0%, rgba(7,7,6,.06) 20%, rgba(7,7,6,.14) 66%, rgba(7,7,6,.84) 100%)}
/* Real 16mm grain from his own plate. Dark plate (mean luminance 14.5/255), so
   screen is the right blend and the speckles do the work. Native pixel scale,
   which is what keeps grain reading as grain. Accent layer only: stage and CTA. */
.grain{position:absolute;inset:0;z-index:4;pointer-events:none;
  background-image:url('img/grain-16mm.jpg');
  background-size:1024px 1024px;background-repeat:repeat;
  mix-blend-mode:screen;opacity:.38}
.hr{position:absolute;left:0;right:0;top:77.9%;height:1px;background:var(--rule);z-index:5;
  opacity:0;animation:fade 1.4s ease .65s forwards}
.hr b{position:absolute;top:-3px;width:1px;height:7px;background:rgba(242,240,234,.34)}
@keyframes fade{to{opacity:1}}

/* hero eases back as the page scrolls over it. `translate`, not `transform`, so it
   composes with .hero's own translateY(-50%) baseline instead of clobbering it.
   Nothing in this list carries .rise: a scroll timeline would override the
   entrance and freeze the element at opacity:0 forever. */
@supports (animation-timeline: scroll()){
  .stage .hero,.stage .under,.stage .status{
    animation:stageaway linear both;
    animation-timeline:scroll(root);
    animation-range:0 100svh}
  .stage .hr{
    animation:fade 1.4s ease .65s forwards, stageaway linear both;
    animation-timeline:auto, scroll(root);
    animation-range:normal, 0 100svh}
  @keyframes stageaway{to{opacity:0;translate:0 -22svh}}
}

.hero{position:absolute;z-index:7;left:var(--l2);right:var(--edge);top:64.5%;
  transform:translateY(-50%)}
.who{display:inline-flex;align-items:center;gap:.75em;
  font-size:clamp(10px,min(.78vw,1.5vh),26px);letter-spacing:.07em;text-transform:uppercase;
  font-weight:500;color:var(--bone);margin-bottom:1.15em}
.who s{width:1.7em;height:2px;background:var(--signal);display:block;
  text-decoration:none;flex:none}
.namerow{display:flex;align-items:center;gap:clamp(16px,1.9vw,40px)}
.logo{height:calc(1.96 * var(--h1));width:auto;display:block;flex:none;
  filter:drop-shadow(0 2px 26px rgba(7,7,6,.9))}
.stage h1{font-variation-settings:'wdth' 96;font-size:var(--h1);
  text-shadow:0 2px 34px rgba(7,7,6,.55)}

.under{position:absolute;z-index:7;left:0;right:0;top:77.9%;height:22.1%;pointer-events:none}
.under > *{pointer-events:auto}
.col{position:absolute;left:var(--l3);top:6%;width:calc(var(--l4) - var(--l3));
  display:flex;flex-direction:column}
.line{font-size:clamp(10px,min(.76vw,1.32vh),26px);line-height:1.55;letter-spacing:.03em;
  text-transform:uppercase;color:rgba(242,240,234,.94)}
.line b{color:var(--bone);font-weight:500}
.scroll-cue{position:absolute;left:var(--l2);top:44%;
  font-family:var(--mono);font-size:clamp(9px,min(.68vw,1.18vh),22px);
  letter-spacing:.14em;text-transform:uppercase;color:rgba(242,240,234,.80);
  display:flex;align-items:center;gap:.8em}
.scroll-cue i{display:block;width:1px;height:2.6em;background:rgba(242,240,234,.66);
  position:relative;overflow:clip}
.scroll-cue i::after{content:'';position:absolute;left:0;top:-100%;width:1px;height:100%;
  background:var(--bone);animation:drip 2.2s cubic-bezier(.4,0,.2,1) infinite}
@keyframes drip{0%{top:-100%}55%,100%{top:100%}}

.status{position:absolute;left:2.4vw;right:2.4vw;bottom:5.6vh;z-index:7;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-family:var(--mono);font-size:clamp(9px,min(.66vw,1.15vh),22px);letter-spacing:.075em;
  text-transform:uppercase;color:rgba(242,240,234,.8)}
.s1{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.s4{display:flex;align-items:center;gap:.7em;color:var(--bone);flex:none;
  white-space:nowrap;font-variant-numeric:tabular-nums}
.s4 i{width:.5em;height:.5em;border-radius:50%;background:var(--signal);display:block;
  animation:blink 1.8s steps(1,end) infinite}
@keyframes blink{0%,58%{opacity:1}59%,100%{opacity:.15}}

/* entrance */
.js .rise{opacity:0;transform:translateY(16px);
  animation:rise .95s cubic-bezier(.22,.61,.36,1) forwards}
@keyframes rise{to{opacity:1;transform:none}}
.d1{animation-delay:.34s}.d2{animation-delay:.50s}.d3{animation-delay:.68s}
.d4{animation-delay:.84s}.d5{animation-delay:.98s}.d6{animation-delay:1.12s}
.d7{animation-delay:1.26s}

/* short desktop windows: lift the divider so the lower block never clips */
@media(min-width:901px) and (max-height:980px){
  .hr{top:73%}.under{top:73%;height:27%}.hero{top:60%}
}
@media(min-width:901px) and (max-height:700px){
  .hr{top:70%}.under{top:70%;height:30%}.hero{top:56%}
}
/* phones: the four-column geometry collapses to one readable column */
@media(max-width:900px){
  .stage{height:100svh}
  .hero{left:var(--pad);right:var(--pad);top:auto;bottom:34%;transform:none}
  .stage h1{font-size:clamp(34px,10.5vw,62px)}
  .logo{height:clamp(58px,17vw,104px)}
  .hr{top:auto;bottom:29%}
  .under{top:auto;bottom:0;height:29%}
  .col{left:var(--pad);right:var(--pad);width:auto;top:14%}
  .line{font-size:clamp(11px,3.1vw,15px)}
  .scroll-cue{display:none}
  .status{bottom:3.2vh}
  .s1{left:var(--pad)}
  .s4{left:auto;right:var(--pad)}
}

/* ═══════════ BELOW THE STAGE ═══════════
   main slides over the pinned stage: that IS the parallax. */
main{position:relative;z-index:6;background:var(--void);
  box-shadow:0 -30px 80px rgba(7,7,6,.85)}
main::before{content:'';position:absolute;left:0;right:0;top:-14svh;height:14svh;
  pointer-events:none;background:linear-gradient(to bottom,
    rgba(7,7,6,0) 0%, rgba(7,7,6,.55) 52%, rgba(7,7,6,.88) 80%, var(--void) 100%)}

.js .rv{opacity:0;transform:translateY(14px);
  transition:opacity .6s var(--eo),transform .6s var(--eo)}
.rv.in{opacity:1;transform:none}

.sec{padding:var(--sec) var(--pad);position:relative}
.wrap{max-width:1560px;margin:0 auto}
.tag{display:flex;align-items:center;gap:.75em;margin-bottom:clamp(18px,2.4vh,34px)}
.tag s{width:1.9em;height:2px;background:var(--signal);flex:none;text-decoration:none}
.tag span{font-family:var(--mono);font-size:var(--lbl);letter-spacing:.19em;
  text-transform:uppercase;color:var(--muted)}
.head{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(20px,3vw,64px);align-items:end;margin-bottom:clamp(36px,6vh,84px)}
.head h2{font-size:var(--h2);font-variation-settings:'wdth' 92;max-width:18ch}
.head p{font-size:var(--txt);color:rgba(242,240,234,.74);max-width:62ch;line-height:1.7}
@media(max-width:820px){.head{grid-template-columns:1fr;align-items:start;gap:18px}}


/* ═══════════ TRUSTED BY: nine real logos, static, evenly spaced ═══════════
   No marquee, no hover trick, no counter: the brief is explicit that the logos
   speak by being there. Nine files exist, nine are shown, the row is not padded. */
.trusted{padding:clamp(48px,7vh,96px) var(--pad);border-top:1px solid var(--rule);
  border-bottom:1px solid var(--rule)}
.tlabel{display:block;text-align:center;font-family:var(--mono);font-size:var(--lbl);
  letter-spacing:.19em;text-transform:uppercase;color:var(--muted);
  margin-bottom:clamp(26px,4vh,48px)}
.logos{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:clamp(22px,3.4vw,56px) clamp(26px,3.4vw,64px);
  max-width:1560px;margin:0 auto}
.logos img{height:clamp(22px,2.2vw,34px);width:auto;max-width:100%;flex:none;
  object-fit:contain;opacity:.82}
/* the two wordmarks that are far narrower than the rest get a touch more height,
   measured off the files, so the row reads as one optical weight */
.logos img.tall{height:clamp(30px,3vw,46px)}
/* An emblem among wordmarks reads as a speck at a shared cap height: measured at
   1440 it came out 23x32 next to 164x32 neighbours. Sized by optical area instead. */
.logos img.mark{height:clamp(40px,3.9vw,58px)}
@media(max-width:560px){.logos{gap:clamp(20px,6vw,34px) clamp(22px,7vw,40px)}}


/* ═══════════ HET WERK: the wall ═══════════
   Full bleed means no container. The grid runs edge to edge at 100% width with
   zero page gutter, and the tiles sit against each other separated only by a
   1px --rule, which is the grid gap showing through. The wall reads as one
   surface rather than as cards floating on a background. */
.werk{padding:0 0 clamp(56px,9vh,118px)}
.whead{padding:var(--sec) var(--pad) clamp(22px,3.6vh,44px);max-width:1560px;margin:0 auto}
.whead h2{font-size:var(--h2);font-variation-settings:'wdth' 92;max-width:18ch}

/* the filter row is the one piece of chrome allowed to stick */
.filterrow{display:none;position:sticky;top:var(--hdh);z-index:30;
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
  background:rgba(7,7,6,.92);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.js .filterrow{display:block}
.filterin{display:flex;align-items:stretch;overflow-x:auto;scrollbar-width:none;
  -ms-overflow-style:none;scroll-snap-type:x proximity}
.filterin::-webkit-scrollbar{display:none}
.fbtn{flex:none;display:inline-flex;align-items:center;gap:.6em;
  padding:clamp(13px,1.7vh,20px) clamp(14px,1.5vw,26px);
  background:none;border:0;border-right:1px solid var(--rule);cursor:pointer;
  font-family:var(--mono);font-size:var(--lbl);letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap;scroll-snap-align:start;
  transition:color .25s ease,background .25s ease}
.fbtn:hover{color:var(--bone)}
.fbtn.on{color:var(--bone);background:rgba(242,240,234,.05)}
.fbtn.on .fcount{color:var(--signal)}
.fcount{font-style:normal;color:var(--dim);font-variant-numeric:tabular-nums;
  transition:color .25s ease}

/* the wall itself */
.wall{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1px;background:var(--rule);border-top:1px solid var(--rule);
  border-bottom:1px solid var(--rule)}
@media(max-width:899px){.wall{grid-template-columns:minmax(0,1fr)}}

/* every tile is 16/9. The first tile of the active filter opens the wall
   one-up, full bleed, and JS moves that class on every filter change. */
.tile{position:relative;background:var(--void);aspect-ratio:16/9;overflow:clip;
  isolation:isolate}
.tile.lead{grid-column:1/-1}
.tile.off{display:none}

.play{position:absolute;inset:0;display:block;background:var(--void)}
.play img{width:100%;height:100%;object-fit:cover;display:block}
/* Two scrim layers, and the reason is the tile height.
   The percentage layer is the look: a long soft fall that reads well on a big tile.
   But percentages scale with the tile, and on a phone a tile is only ~180px tall, so
   that fall collapses to nothing exactly where the caption sits and the client name
   was measuring as low as 2.2:1 over a pale poster. The pixel layer fixes that: the
   caption always sits within ~120px of the bottom at every viewport, so a scrim
   measured in pixels covers it identically at 320 and at 1440. On a tall tile the
   percentage layer already dominates that band, so this costs the desktop look
   almost nothing. Neither layer touches the image: both are void over it. */
.play::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to top,rgba(7,7,6,.68) 0,rgba(7,7,6,.62) 68px,
      rgba(7,7,6,.46) 108px,rgba(7,7,6,0) 160px),
    linear-gradient(to top,rgba(7,7,6,.96) 0%,rgba(7,7,6,.86) 18%,
      rgba(7,7,6,.52) 36%,rgba(7,7,6,0) 58%)}
.pbtn{position:absolute;left:50%;top:50%;translate:-50% -50%;z-index:2;
  width:clamp(52px,4.4vw,76px);height:clamp(52px,4.4vw,76px);
  display:grid;place-items:center;color:var(--bone);
  border:1px solid rgba(242,240,234,.55);background:rgba(7,7,6,.40);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:background .3s var(--eo),border-color .3s var(--eo)}
@media(hover:hover) and (pointer:fine){
  .play:hover .pbtn,.play:focus-visible .pbtn{background:var(--signal);border-color:var(--signal)}
}
.play:active .pbtn{transform:scale(.97)}

/* client, film, category. Over the poster, bottom left. */
.tmeta{position:absolute;left:0;bottom:0;z-index:3;pointer-events:none;
  padding:clamp(14px,1.7vw,30px);display:flex;flex-direction:column;gap:.24em;
  max-width:min(88%,62ch)}
.tmeta b{font-family:var(--disp);font-weight:700;text-transform:uppercase;
  font-variation-settings:'wdth' 92;letter-spacing:-.004em;line-height:1.02;
  font-size:clamp(15px,1.45vw,27px);color:var(--bone)}
.ttitle{font-size:clamp(11.5px,.82vw,16px);line-height:1.45;color:rgba(242,240,234,.82)}
/* The role credit reads in bone and lets red carry the border and the left rule.
   Signal red on void tops out at 4.45:1, so red text here could never reach 4.5
   at any scrim strength: the colour was the ceiling, not the scrim. Bone clears
   it outright and the red still marks the line as a credit rather than a title. */
.tcredit{font-family:var(--mono);font-size:clamp(9px,.62vw,12px);letter-spacing:.12em;
  text-transform:uppercase;color:var(--bone);line-height:1.4;
  align-self:flex-start;margin-top:.45em;padding:.45em .8em;
  border:1px dashed rgba(228,41,34,.5);border-left:2px solid var(--signal);
  background:rgba(228,41,34,.05)}
.tcat{margin-top:.5em;font-family:var(--mono);font-size:clamp(9px,.62vw,12px);
  letter-spacing:.17em;text-transform:uppercase;color:var(--muted)}

/* the film itself, created on the click and never before */
.tile video{position:absolute;inset:0;width:100%;height:100%;z-index:4;
  background:var(--void);object-fit:contain;display:block}
.tile.playing .play,.tile.playing .tmeta{display:none}

/* ═══════════ OVER MIJ: the about page's band, full bleed ═══════════
   The layers and both gradients are copied verbatim from site/style.css so this
   band and the future About page stay identical. The gradient runs "to right",
   so 0% (darkest) lands on the LEFT where the copy sits and the frame stays open
   on the RIGHT, which is where the standing rule wants the subject. */
.storyband{position:relative;display:flex;align-items:center;overflow:clip;
  isolation:isolate;min-height:clamp(520px,74svh,860px);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.storyband .bg{position:absolute;inset:0;z-index:0;overflow:clip;background:var(--void)}
.storyband .bg img{width:100%;height:100%;object-fit:cover;object-position:64% 26%}
.storyband .side{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to right,
    rgba(7,7,6,.93) 0%, rgba(7,7,6,.80) 24%, rgba(7,7,6,.46) 47%,
    rgba(7,7,6,.16) 70%, rgba(7,7,6,.06) 100%)}
.storyband .fall{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(to bottom,rgba(7,7,6,0.620) 0.0%,rgba(7,7,6,0.579) 2.3%,rgba(7,7,6,0.475) 4.7%,rgba(7,7,6,0.340) 7.0%,rgba(7,7,6,0.205) 9.3%,rgba(7,7,6,0.101) 11.7%,rgba(7,7,6,0.060) 14.0%,rgba(7,7,6,0.072) 18.3%,rgba(7,7,6,0.101) 22.7%,rgba(7,7,6,0.140) 27.0%,rgba(7,7,6,0.179) 31.3%,rgba(7,7,6,0.208) 35.7%,rgba(7,7,6,0.220) 40.0%,rgba(7,7,6,0.248) 43.0%,rgba(7,7,6,0.319) 46.0%,rgba(7,7,6,0.410) 49.0%,rgba(7,7,6,0.501) 52.0%,rgba(7,7,6,0.572) 55.0%,rgba(7,7,6,0.600) 58.0%,rgba(7,7,6,0.613) 60.7%,rgba(7,7,6,0.647) 63.3%,rgba(7,7,6,0.690) 66.0%,rgba(7,7,6,0.733) 68.7%,rgba(7,7,6,0.767) 71.3%,rgba(7,7,6,0.780) 74.0%,rgba(7,7,6,0.788) 76.3%,rgba(7,7,6,0.809) 78.7%,rgba(7,7,6,0.835) 81.0%,rgba(7,7,6,0.861) 83.3%,rgba(7,7,6,0.882) 85.7%,rgba(7,7,6,0.890) 88.0%,rgba(7,7,6,0.894) 90.0%,rgba(7,7,6,0.903) 92.0%,rgba(7,7,6,0.915) 94.0%,rgba(7,7,6,0.927) 96.0%,rgba(7,7,6,0.936) 98.0%,rgba(7,7,6,0.940) 100.0%)}
.storyband .grain{z-index:4}
.storyin{position:relative;z-index:6;margin-right:auto;
  width:min(52ch,48vw);padding:clamp(44px,8vh,110px) var(--pad)}
.storyin h2{font-size:var(--h2);font-variation-settings:'wdth' 92;
  margin-bottom:clamp(18px,2.6vh,34px);max-width:16ch;
  text-shadow:0 2px 26px rgba(7,7,6,.6)}
.storyin p{color:rgba(242,240,234,.88);margin-bottom:1.05em;line-height:1.72;
  text-shadow:0 1px 16px rgba(7,7,6,.55)}
.storyin p:last-of-type{margin-bottom:0}
.storyin .langs{font-family:var(--mono);font-size:var(--lbl);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(242,240,234,.82);
  margin-top:clamp(20px,3vh,36px);padding-top:clamp(14px,2vh,22px);
  border-top:1px solid var(--rule)}

/* Phones: the site's own rule, the side gradient comes off so the frame is not
   fighting the copy. The column goes full width, and .fall plus the text shadow
   carry the contrast from there. Placed after the base rules, not in the earlier
   mobile block, or the base width wins on source order. */
@media(max-width:900px){
  .storyband{min-height:0}
  .storyband .side{background:none}
  .storyin{width:auto;margin-right:0;padding:clamp(56px,9vh,96px) var(--pad)}
  .storyin h2{max-width:none}
  .storyin p{max-width:42ch}
}

/* ═══════════ THE SITE LINK ═══════════ */
.siteband{border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
  padding:clamp(46px,7vh,92px) var(--pad)}
.siteband .wrap{display:flex;flex-wrap:wrap;gap:clamp(20px,3vw,56px);
  align-items:center;justify-content:space-between}
.siteband h2{font-size:clamp(20px,2.1vw,38px);font-variation-settings:'wdth' 92;
  max-width:20ch;margin-bottom:.7em}
.siteband p{color:rgba(242,240,234,.74);max-width:52ch}

/* buttons: readable as tappable without hover: visible border and fill, real height */
.btn{display:inline-flex;align-items:center;gap:.7em;min-height:54px;
  padding:0 clamp(18px,1.6vw,32px);
  font-family:var(--mono);font-size:clamp(10px,.72vw,14px);letter-spacing:.16em;
  text-transform:uppercase;border:1px solid var(--bone);background:var(--bone);
  color:var(--void);white-space:nowrap;cursor:pointer;
  transition:background .3s var(--eo),color .3s var(--eo),border-color .3s var(--eo),
    box-shadow .3s var(--eo),transform .16s var(--eo)}
.btn:hover,.btn:focus-visible{background:var(--signal);border-color:var(--signal);color:#fff}
.btn:active{transform:scale(.97)}
.btn.ghost{background:rgba(7,7,6,.34);color:rgba(242,240,234,.92);
  border-color:rgba(242,240,234,.30)}
.btn.ghost:hover,.btn.ghost:focus-visible{color:#fff;border-color:var(--signal);
  background:rgba(228,41,34,.14);
  box-shadow:0 0 0 1px rgba(228,41,34,.35), 0 0 22px rgba(228,41,34,.22)}
.btn svg{width:1.35em;height:1.35em;flex:none;stroke:currentColor;fill:none;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* ═══════════ CTA ═══════════ */
.cta{position:relative;overflow:clip;isolation:isolate;
  padding:clamp(86px,14vh,190px) var(--pad);text-align:left}
.cta .bgfix{position:absolute;inset:0;z-index:0;background-size:cover;
  background-position:center 38%;
  background-image:image-set(url('img/about-set-f1.webp') type('image/webp'),
    url('img/about-set-f1.jpg') type('image/jpeg'))}
.cta .scrim{position:absolute;inset:0;z-index:1;background:
  linear-gradient(to right,rgba(7,7,6,.94) 0%,rgba(7,7,6,.82) 38%,rgba(7,7,6,.48) 100%),
  linear-gradient(to bottom,rgba(7,7,6,.9) 0%,rgba(7,7,6,.3) 40%,rgba(7,7,6,.92) 100%)}
.cta .grain{z-index:2}
.cta .wrap{position:relative;z-index:3}
.cue{display:flex;align-items:center;gap:.7em;margin-bottom:clamp(14px,2vh,28px)}
.cue s{width:1.7em;height:2px;background:var(--signal);display:block;
  text-decoration:none;flex:none}
.cue span{font-family:var(--disp);font-variation-settings:'wdth' 96;font-weight:700;
  text-transform:uppercase;letter-spacing:.045em;color:var(--bone);
  font-size:clamp(13px,min(1.02vw,1.78vh),34px)}
.cta h2{font-size:var(--h2);font-variation-settings:'wdth' 92;max-width:17ch;
  margin-bottom:clamp(16px,2.4vh,30px)}
.cta p{color:rgba(242,240,234,.84);max-width:54ch;margin-bottom:clamp(26px,4vh,46px)}
.acts{display:flex;flex-wrap:wrap;gap:clamp(18px,2vw,34px)}
/* A mailto: does nothing on a machine with no default mail client, and a wa.me
   link does nothing without WhatsApp. The address and the number are printed as
   real, selectable text under each button so they can always be read or copied. */
.act{display:flex;flex-direction:column;align-items:flex-start;gap:.85em}
.actline{font-family:var(--mono);font-size:clamp(10px,.74vw,13.5px);letter-spacing:.07em;
  color:rgba(242,240,234,.88);white-space:nowrap;
  -webkit-user-select:text;user-select:text}

/* ═══════════ FOOTER ═══════════ */
footer{border-top:1px solid var(--rule);padding:clamp(46px,7vh,88px) var(--pad) 0;
  position:relative;z-index:6;background:var(--void)}
.fgrid{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(24px,4vw,70px);
  align-items:start;max-width:1560px;margin:0 auto}
.sig{font-family:var(--disp);font-weight:700;font-variation-settings:'wdth' 92;
  font-size:clamp(17px,1.5vw,24px);text-transform:uppercase;margin-bottom:.8em}
.fgrid p{color:rgba(242,240,234,.72);max-width:48ch}
.fcon{font-family:var(--mono);font-size:var(--lbl);letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted);line-height:2.2;text-align:right}
.fcon a{display:block;color:var(--muted);transition:color .25s ease}
.fcon a:hover,.fcon a:focus-visible{color:var(--bone)}
.fcon a.mail{text-transform:none;letter-spacing:.06em}
.fbar{display:flex;flex-wrap:wrap;gap:10px 24px;justify-content:space-between;
  max-width:1560px;margin:clamp(34px,5vh,64px) auto 0;
  padding:clamp(16px,2.4vh,26px) 0;border-top:1px solid var(--rule);
  font-family:var(--mono);font-size:var(--lbl);letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim)}
@media(max-width:760px){
  .fgrid{grid-template-columns:1fr;gap:26px}
  .fcon{text-align:left}
}

/* ═══════════ REDUCED MOTION: gentler, not zero ═══════════
   Opacity fades survive so reveals still read as intentional; transforms,
   the blink, the drip and the ken-burns-style scroll drift are removed. */
@media(prefers-reduced-motion:reduce){
  .js .rise{opacity:0;transform:none;animation:fade .4s ease forwards}
  .js .rv{transform:none;transition:opacity .3s ease}
  .s4 i{animation:none}
  .scroll-cue i::after{animation:none;top:0}
  .reel{transition:opacity .3s ease}
  .btn:active{transform:none}
  @supports (animation-timeline: scroll()){
    .stage .hero,.stage .under,.stage .status,.stage .hr{animation-timeline:auto;
      animation-range:normal}
    .stage .hero,.stage .under,.stage .status{animation:none}
    .stage .hr{animation:fade 1.4s ease .65s forwards}
  }
}
/* touch: no hover chrome */
@media(hover:none),(pointer:coarse){
  .btn:hover{background:var(--bone);border-color:var(--bone);color:var(--void)}
  .btn.ghost:hover{background:rgba(7,7,6,.34);color:rgba(242,240,234,.92);
    border-color:rgba(242,240,234,.30);box-shadow:none}
}
