/* ============================================================
   Particle hero + loader — DESKTOP ONLY (min-width 769px)

   Ported from the vishal-portfolio.bvishal994.workers.dev hero. Unlike the
   rest of the page this is not an artboard: it is a 100svh screen with the
   reference's own px values, which came off a 1440x900 comp.

   The phone keeps the old 390 artboard hero (.stage-wrap, css/mobile.css),
   so the two swap at the same 768px breakpoint main.js uses.

   Section 2 slides up over it. The reference did that with a sticky hero;
   here the hero's content is a FIXED layer (.phero__pin) clipped to the
   hero's own box by clip-path, which clips fixed descendants where overflow
   cannot. Same picture, and nothing below the hero needs a z-index or an
   opaque ground to cover it.

   Colours are literal: like the old hero, this one is exempt from the
   light/dark toggle.
   ============================================================ */

.phero, .loader { display: none; }

@media (min-width: 769px) {

  /* the old artboard hero and its curtain intro are the phone's now */
  .stage-wrap, .curtain { display: none; }

  .phero {
    --ph-pad-left: 45px;
    --ph-pad-right: 40px;
    --ph-micro-size: 11px;
    --ph-micro-track: 0.09em;

    display: block;
    position: relative;
    width: 100%;
    height: 100vh;
    height: 100svh;
    min-height: 560px;
    background: #000;
    color: #fff;
    font-family: "Helvetica Neue", Helvetica, Arial, "Segoe UI", Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: auto;
    clip-path: inset(0);
  }

  .phero__pin {
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: #000;
  }
  /* Too short to hold the layout: scroll it away like any other block. */
  @media (max-height: 559px) {
    .phero__pin { position: absolute; }
  }

  /* As section 2 covers the hero, the hero dims under a veil and its text
     drifts up a little. Tied to the scroll off the main thread where the
     browser can; elsewhere js/phero.js sets --cover (0 to 1). */
  .phero__pin::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    background: #000;
    opacity: calc(var(--cover, 0) * 0.6);
    pointer-events: none;
  }

  .phero__title,
  .phero__lede,
  .phero__nav,
  .phero__meta {
    transform: translateY(calc(var(--cover, 0) * -60px));
  }

  @supports (animation-timeline: scroll()) {
    .phero__pin::after {
      opacity: 0;
      animation: phero-veil linear both;
      animation-timeline: scroll(root);
      animation-range: 0 100svh;
    }
    .phero__title,
    .phero__lede,
    .phero__nav,
    .phero__meta {
      transform: none;
      animation: phero-drift linear both;
      animation-timeline: scroll(root);
      animation-range: 0 100svh;
    }
  }

  /* The field sits behind everything and never takes the pointer: it tracks
     the cursor on window. */
  .phero__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
    z-index: 0;
  }

  .phero__pin > :not(.phero__canvas) {
    position: absolute;
    z-index: 1;
  }

  .phero__title {
    top: 45px;
    left: var(--ph-pad-left);
    margin: 0;
    max-width: 14em;
    font-size: 46px;
    line-height: 54px;
    font-weight: 400;
    letter-spacing: -0.03em;
    color: #fff;
  }

  /* Anchored to the bottom, so on a short window the lede and the footer
     line keep their distance instead of colliding. */
  .phero__lede {
    bottom: 240px;
    left: var(--ph-pad-left);
    margin: 0;
    font-size: var(--ph-micro-size);
    line-height: 16px;
    font-weight: 400;
    letter-spacing: var(--ph-micro-track);
    text-transform: uppercase;
    color: #fff;
  }

  /* The four labels run down the right edge on an even 94.33px rhythm. */
  .phero__nav {
    top: 40px;
    right: var(--ph-pad-right);
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 83.33px;
  }

  .phero__nav-link {
    white-space: nowrap;
    font-size: var(--ph-micro-size);
    line-height: 11px;
    letter-spacing: var(--ph-micro-track);
    text-transform: uppercase;
    text-decoration: none;
    color: #fff;
    opacity: 0.5;
    transition:
      opacity 0.45s cubic-bezier(0.2, 0.7, 0.2, 1),
      font-size 0.45s cubic-bezier(0.2, 0.7, 0.2, 1),
      transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  /* The hovered label grows as well as brightens. The line box stays 11px
     so the rhythm holds, and the nudge keeps its cap height in line. */
  .phero__nav-link:hover,
  .phero__nav-link:focus-visible {
    font-size: 14px;
    opacity: 1;
    transform: translateY(2px);
  }

  .phero__meta {
    left: var(--ph-pad-left);
    right: var(--ph-pad-right);
    bottom: 104px;
    display: flex;
    justify-content: space-between;
    gap: 24px;
    font-size: var(--ph-micro-size);
    line-height: 11px;
    letter-spacing: var(--ph-micro-track);
    text-transform: uppercase;
    color: #fff;
  }

  /* The side menu's Experience lands on this label inside About. Without a
     margin it would sit flush at the window's top edge, under the pill. */
  .s10__label--exp { scroll-margin-top: calc(140px * var(--k)); }

  .phero :focus-visible {
    outline: 1px solid rgba(255, 255, 255, 0.7);
    outline-offset: 4px;
  }

  /* The nav layer (only the theme toggle, now the pill is gone from this
     page) waits until the hero has gone. js/phero.js sets html.on-phero
     while the hero is under it. */
  .navlayer {
    transition: opacity 0.45s ease, visibility 0s linear 0s;
  }
  .on-phero .navlayer {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.45s ease, visibility 0s linear 0.45s;
  }

  /* ---------- the loader ----------
     His disciplines flash in the middle, above a line that fills as the page
     loads; then the two halves of the screen part along the line.
     html.loading (set in the head) shows it from the first paint. */
  .has-loader body { animation: none; opacity: 1; }

  .loading .loader {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: block;
    color: #fff;
    font-family: "Helvetica Neue", Helvetica, Arial, "Segoe UI", Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  .loading:not(.loader-open) { overflow: hidden; }
  .loader-open .loader { pointer-events: none; }

  .loader__half {
    position: absolute;
    left: 0;
    right: 0;
    height: 50%;
    background: #000;
    transition: transform 1s cubic-bezier(0.76, 0, 0.24, 1);
  }
  .loader__half--top { top: 0; }
  .loader__half--bottom { bottom: 0; }
  .loader-open .loader__half--top { transform: translateY(-100%); }
  .loader-open .loader__half--bottom { transform: translateY(100%); }

  .loader__word {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 44px;
    font-size: clamp(40px, 6vw, 80px);
    line-height: 1;
    letter-spacing: -0.03em;
    text-align: center;
    white-space: nowrap;
  }
  .loader__word span {
    display: inline-block;
    animation: loader-word 0.32s ease both;
  }

  .loader__label,
  .loader__pct {
    position: absolute;
    bottom: 16px;
    font-size: 11px;
    line-height: 11px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
  }
  .loader__label { left: 45px; }
  .loader__pct { right: 40px; }

  .loader__line {
    position: absolute;
    top: 50%;
    left: 45px;
    right: 40px;
    height: 1px;
    background: rgba(255, 255, 255, 0.14);
    transition: opacity 0.4s ease;
  }
  .loader__line i {
    position: absolute;
    inset: 0;
    background: #fff;
    transform: scaleX(0);
    transform-origin: left center;
  }
  .loader-open .loader__line { opacity: 0; }
}

/* ============================================================
   Closing screen (.pfoot) — DESKTOP ONLY

   Vishal's "Desktop - bottom" comp (1440x900, 2026-09-27): the hero's
   particle field again, one line centred over it, the three contact links
   and the colophon. It takes over s10's contact row on desktop; the phone
   keeps that row (css/mobile.css) and never shows this block.

   Built like the hero, not like the artboards: a 100svh screen at the
   comp's own px. The field is a FIXED layer clipped to the section by
   clip-path, so it is uncovered from under About as the page ends, and it
   reads the cursor on window as the hero's does. The type is NOT in that
   layer: it scrolls in with the section, so the sitewide letter rise
   (js/text-motion.js) sees it arrive, and it lands on the comp's positions
   exactly when the page bottoms out.

   x values are the comp's, in a 1440 frame centred on the window. The line
   holds the middle (where the field's two forms are); the links and the
   colophon hold the bottom. Exempt from the theme, like the hero.
   ============================================================ */
.pfoot { display: none; }

@media (min-width: 769px) {
  .s10__link, .s10__colophon { display: none; }

  .pfoot {
    display: block;
    position: relative;
    width: 100%;
    height: 100vh;
    height: 100svh;
    min-height: 560px;
    overflow: hidden;          /* the 1440 frame, on narrower windows */
    clip-path: inset(0);       /* the fixed field, which overflow cannot clip */
    background: #000;
    color: #fff;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .pfoot__pin {
    position: fixed;
    inset: 0;
    background: #000;
    pointer-events: none;
  }
  .pfoot__canvas { display: block; width: 100%; height: 100%; }

  .pfoot__frame {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 1440px;
    margin-left: -720px;
  }

  /* Helvetica Neue Light 35; baseline at comp y 466, 16 below the middle */
  .pfoot__title {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(50% - 14.5px);
    margin: 0;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-weight: 300;
    font-size: 35px;
    line-height: 35px;
    text-align: center;
    white-space: nowrap;
  }

  /* Editorial New Ultralight Italic 20; baseline at comp y 765.2 */
  .pfoot__link {
    position: absolute;
    top: calc(100% - 150.3px);
    font-family: 'PP Editorial New', Georgia, serif;
    font-style: italic;
    font-weight: 200;
    font-size: 20px;
    line-height: 20px;
    color: #fff;
    white-space: nowrap;
    text-decoration: none;
  }
  .pfoot__link:hover { text-decoration: underline; text-underline-offset: 4px; }
  .pfoot__link:focus-visible { outline: 1px solid rgba(255, 255, 255, 0.7); outline-offset: 4px; }
  .pfoot__arrow { position: absolute; top: -0.908px; overflow: visible; }

  /* Neue Montreal Book 15 at 40%; baseline at comp y 860 */
  .pfoot__colophon {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% - 53px);
    margin: 0;
    font-family: 'PP Neue Montreal', Helvetica, Arial, sans-serif;
    font-weight: 350;
    font-size: 15px;
    line-height: 15px;
    text-align: center;
    color: #fff;
    opacity: 0.4;
    white-space: nowrap;
  }
}

@keyframes phero-veil { to { opacity: 0.6; } }
@keyframes phero-drift { to { transform: translateY(-60px); } }
@keyframes loader-word {
  from { opacity: 0; filter: blur(8px); transform: translateY(8px); }
  to { opacity: 1; filter: none; transform: none; }
}

/* ---------- narrower desktop windows ---------- */
@media (min-width: 769px) and (max-width: 1100px) {
  .phero__title { font-size: 38px; line-height: 45px; }
}

@media (min-width: 769px) and (max-width: 820px) {
  .phero { --ph-pad-left: 24px; --ph-pad-right: 24px; }
  .phero__pin {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 88px var(--ph-pad-right) 40px var(--ph-pad-left);
  }
  .phero__pin > :not(.phero__canvas) { position: static; }
  .phero__title { font-size: 32px; line-height: 39px; max-width: 100%; }
  .phero__lede { margin-top: auto; padding-top: 48px; }
  .phero .phero__nav {
    position: absolute;
    top: 32px;
    left: var(--ph-pad-left);
    right: var(--ph-pad-right);
    flex-direction: row;
    align-items: baseline;
    justify-content: flex-start;
    gap: 20px;
  }
  .phero__nav-link:hover,
  .phero__nav-link:focus-visible {
    font-size: var(--ph-micro-size);
    transform: none;
  }
  .phero__meta { margin-top: 32px; flex-direction: column; gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .phero__pin::after,
  .phero__title,
  .phero__lede,
  .phero__nav,
  .phero__meta { animation: none; }
}
@media (min-width: 769px) and (prefers-reduced-motion: reduce) {
  .navlayer, .on-phero .navlayer { transition: none; }
}
