  :root{
    --ink:      #0B0C10;   /* cold near-black background        */
    --ink-2:    #070709;   /* deeper wells                      */
    --silver:   #D3D7DE;   /* primary text (metallic)           */
    --mercury:  #EEF1F4;   /* headlines / highlights            */
    --pewter:   #868D98;   /* secondary / muted text            */
    --pewter-2: #737A85;   /* faint metadata — 4.5:1 on --ink, AA */
    --line:     rgba(211,215,222,0.14);
    --line-2:   rgba(211,215,222,0.07);
    --gold:      #C9A667;   /* award callouts — muted brass, not bright yellow */
    --gold-soft: rgba(201,166,103,.68);

    --wide: 125;           /* Archivo width axis                */
    --reg:  100;

    --ease: cubic-bezier(.2,.7,.2,1);
    --max: 1200px;
    --pad: clamp(1.25rem, 5vw, 4rem);

    /* vertical rhythm — shared by the gaps between text blocks on the
       Hero and Connect sections, so spacing reads as one deliberate
       scale rather than per-block guesswork                          */
    --space-xs: clamp(1rem,   2.2vh, 1.4rem);
    --space-sm: clamp(1.25rem, 3vh,  2rem);
    --space-md: clamp(2rem,   4.5vh, 3rem);
    --space-lg: clamp(3.75rem, 8.75vh, 5.6rem);
    --space-xl: clamp(4rem,   9vh,   6rem);
  }

  *{ box-sizing:border-box; margin:0; padding:0; }

  html{ scroll-behavior:smooth; }
  @media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

  body{
    background:var(--ink);
    color:var(--silver);
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' var(--reg),'wght' 400;
    font-size:clamp(1rem, 0.95rem + 0.2vw, 1.125rem);
    line-height:1.65;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
    overflow-x:hidden;
  }

  /* ambient screen texture: vignette + faint grain ------------------- */
  body::before{
    content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
    background:
      radial-gradient(120% 90% at 50% 0%, transparent 55%, rgba(0,0,0,.55) 100%),
      radial-gradient(80% 60% at 50% 40%, rgba(120,140,170,.05), transparent 70%);
  }
  body::after{
    content:""; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.035;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  }

  .wrap{ max-width:var(--max); margin-inline:auto; padding-inline:var(--pad); }
  .mono{ font-family:'IBM Plex Mono', ui-monospace, monospace; }

  /* shared "label" treatment for small mono meta text — Connect's link
     row reads as a quiet secondary list                                */
  .ab-socials a{
    font-family:'IBM Plex Mono', monospace;
    font-size:.8rem;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--mercury);
    opacity:.62;
    transition:opacity .3s var(--ease);
  }

  /* the hero's identity anchor — credit above the statement, name below
     it. Same mono/uppercase family as the label style above, but sized
     and lit up further so name + credit read as the load-bearing
     information on the page, not a caption to the statement.           */
  .hero-kicker,
  .hero-signature{
    font-family:'IBM Plex Mono', monospace;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--mercury);
  }
  .hero-kicker,
  .hero-signature{ font-size:clamp(1.02rem,1.7vw,1.22rem); font-weight:600; opacity:.8; }

  a{ color:inherit; text-decoration:none; }

  :focus-visible{
    outline:2px solid var(--mercury);
    outline-offset:3px;
    border-radius:2px;
  }

  .visually-hidden{
    position:absolute; width:1px; height:1px;
    padding:0; margin:-1px; overflow:hidden;
    clip:rect(0,0,0,0); white-space:nowrap; border:0;
  }

  .skip-link{
    position:absolute; left:1rem; top:-3.5rem; z-index:200;
    padding:.75rem 1.25rem;
    background:var(--mercury); color:var(--ink);
    font-family:'IBM Plex Mono', monospace;
    font-size:.8rem; letter-spacing:.06em; text-transform:uppercase;
    border-radius:2px;
    transition:top .2s var(--ease);
  }
  .skip-link:focus{ top:1rem; }

  /* ------------------------------------------------------------------ */
  /* SECTION SCAFFOLD                                                   */
  /* ------------------------------------------------------------------ */
  section{ position:relative; z-index:1; }
  .band{ padding-block:clamp(2.25rem, 5.85vh, 4.5rem); }
  .band + .band{ border-top:1px solid var(--line-2); }

  .sec-head{
    display:flex; align-items:baseline; gap:1rem;
    margin-bottom:clamp(1.3rem,3.25vh,2.25rem);
  }
  .sec-head h2{
    font-variation-settings:'wdth' var(--wide),'wght' 720;
    font-size:clamp(1.5rem,4.5vw,2.7rem); text-transform:uppercase;
    letter-spacing:0; color:var(--mercury); line-height:1;
  }

  /* scroll reveal */
  .reveal{ opacity:0; transform:translateY(20px); transition:opacity .7s var(--ease), transform .7s var(--ease); }
  .reveal.in{ opacity:1; transform:none; }
  @media (prefers-reduced-motion: reduce){
    .reveal{ opacity:1; transform:none; transition:none; }
  }

  /* ------------------------------------------------------------------ */
  /* HERO — full-bleed photo landing                                    */
  /* ------------------------------------------------------------------ */
  .hero{
    position:relative;
    min-height:100vh; min-height:100svh;
    overflow:hidden;
  }
  .hero-media{
    position:absolute; inset:0; z-index:0;
    background-image:url("images/portrait.webp");
    background-size:cover; background-position:center 60%;
  }
  .hero-scrim{
    position:absolute; inset:0; z-index:1;
    background:
      /* soft, tightly-scoped dimmer over the sun itself (pixel-sampled
         from the source photo) — takes the raw highlight down a touch
         without flattening the rest of the sky                          */
      radial-gradient(circle at 62% 39%, rgba(6,7,10,.22) 0%, rgba(6,7,10,.1) 9%, transparent 19%),
      /* listed first so it paints ON TOP of the washes below — otherwise
         they tint the bottom edge darker than --ink and the hand-off to
         Work Samples shows as a step. Kept short so the headlights
         further up the ridge stay untouched.                           */
      linear-gradient(to top, rgba(11,12,16,.5) 0%, rgba(11,12,16,.46) 2%, rgba(11,12,16,.28) 7%, rgba(11,12,16,.1) 13%, transparent 26%),
      linear-gradient(100deg, rgba(4,5,7,.31) 0%, rgba(4,5,7,.14) 36%, rgba(4,5,7,.04) 64%, rgba(4,5,7,.18) 100%),
      linear-gradient(to top, rgba(4,5,7,.36) 0%, rgba(4,5,7,.1) 30%, transparent 54%),
      linear-gradient(to bottom, rgba(4,5,7,.16) 0%, transparent 22%);
  }
  .hero-row{
    position:relative; z-index:2; min-height:100vh; min-height:100svh;
    display:flex; align-items:center; justify-content:space-between;
    gap:6vw; padding-block:14vh 12vh;
  }
  /* pulled down from the row's centered position — percentage translate
     is relative to the block's own height, so this reads as "20% lower"
     regardless of viewport size                                        */
  .hero-brand{ transform:translateY(20%); }
  .hero-logo{
    position:relative;
    font-family:'Space Grotesk', system-ui, sans-serif;
    font-weight:700; line-height:.94; letter-spacing:-.02em;
    color:var(--mercury); user-select:none;
  }
  /* small brand mark, pinned to the hero's top-left corner — same size/
     font as the .ab-logo reprise on Connect (the .ab-logo class supplies
     that sizing; this just handles placement over the photo).           */
  .hero-corner-logo{
    position:absolute; z-index:2; top:var(--pad); left:var(--pad); margin:0;
  }
  /* corner mark only (Hero + Connect's top-left reprise) — sized down
     from the base .hero-logo scale so it reads as a quiet signature
     rather than competing with the footer colophon's full-size mark.
     Compound selector (.hero-logo.hero-corner-logo, not a descendant
     combinator) is needed so this out-specifies the base .hero-logo
     .hl-1/.hl-2 rules below — equal-specificity descendant selectors
     would otherwise lose to whichever is later in source order.        */
  .hero-logo.hero-corner-logo .hl-1{ font-size:clamp(1.33rem, 3.5vw, 2.45rem); }
  .hero-logo.hero-corner-logo .hl-2{ font-size:clamp(.98rem, 2.73vw, 1.82rem); }
  .hero-logo .hl-row{ display:flex; align-items:baseline; flex-wrap:wrap; gap:.15rem; }
  .hero-logo .hl-1{ font-size:clamp(1.9rem, 5vw, 3.5rem); }
  .hero-logo .hl-1 .dot{ color:var(--pewter); }
  /* the umlaut redrawn as two dots, sized and centered to read
     deliberately over the "a" rather than as a stray artifact          */
  .hero-logo .a-uml{ position:relative; display:inline-block; }
  .hero-logo .a-uml::before,
  .hero-logo .a-uml::after{
    content:""; position:absolute; top:.075em;
    width:.11em; height:.11em; border-radius:50%;
    background:var(--mercury); opacity:.68;
  }
  .hero-logo .a-uml::before{ left:.145em; }
  .hero-logo .a-uml::after{ right:.145em; }
  /* sits beside the wordmark, plain and legible — quieter weight and
     opacity keep it read as a descriptor of the mark, not a duplicate  */
  .hero-logo .hl-2{
    font-weight:500; color:var(--mercury); opacity:.5;
    font-size:clamp(1.4rem, 3.9vw, 2.6rem);
  }
  .hero-kicker{
    max-width:none;
    line-height:1.6;
  }
  /* a supporting line, not the headline — name and credit above/below it
     are the load-bearing information, so this stays deliberately quieter:
     smaller ceiling, lighter weight, and dimmed a touch off pure white.
     Selector scoped through .hero-brand — .ab-statement's own base rule
     (defined later, in the Connect section) has equal specificity as a
     bare .hero-statement selector and would otherwise win on font-size.
     text-wrap:balance keeps the last line from orphaning a single word. */
  .hero-brand .hero-statement{
    max-width:25ch; margin-top:var(--space-sm);
    font-variation-settings:'wdth' var(--reg),'wght' 440;
    font-size:clamp(1.4rem,2.9vw,2.35rem); line-height:1.22; letter-spacing:-.005em;
    color:var(--silver);
    text-wrap:balance;
  }
  /* quiet signature line closing out the block — name and location on
     one row, well below the statement's weight                        */
  .hero-signature{
    max-width:30rem; margin-top:var(--space-md);
  }
  .hero-signature .hero-location{ display:block; margin-top:.35rem; }
  /* pushed toward the bottom of the row so it reads as a separate block
     from the wordmark rather than centered alongside it — margin-bottom
     lifts it off the very edge so it doesn't crowd the bottom padding   */
  .hero-nav{ display:flex; flex-direction:column; gap:.55em; align-self:flex-end; margin-bottom:8vh; }
  .hero-nav a,
  .hero-nav button{
    display:flex; align-items:baseline; gap:.7em; width:fit-content;
    white-space:nowrap;
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' var(--wide),'wght' 650;
    font-size:clamp(1.05rem, 2.5vw, 1.85rem);
    line-height:1.1;
    color:var(--mercury);
    transition:color .3s var(--ease), transform .3s var(--ease);
  }
  .hero-nav button{ background:none; border:0; padding:0; cursor:pointer; text-align:left; }
  .hero-nav a .n,
  .hero-nav button .n{
    font-family:'IBM Plex Mono', monospace; font-weight:400;
    font-size:.48em; letter-spacing:.02em; color:var(--pewter);
  }
  .hero-nav a:hover, .hero-nav a:focus-visible,
  .hero-nav button:hover, .hero-nav button:focus-visible{ color:var(--silver); transform:translateX(3px); }
  .hero-nav a:hover .n, .hero-nav a:focus-visible .n,
  .hero-nav button:hover .n, .hero-nav button:focus-visible .n{ color:var(--mercury); }

  /* scroll hint, bottom-center of the hero photo — faint by design
     (opacity), with a slow drift rather than a bounce to stay subtle.   */
  .hero-scroll-cue{
    display:flex;
    position:absolute; left:50%; bottom:2.6rem; z-index:2;
    transform:translateX(-50%);
    color:var(--mercury); opacity:.55;
    animation:hero-scroll-cue-drift 2.4s ease-in-out infinite;
  }
  .hero-scroll-cue svg{ width:1.3rem; height:1.3rem; display:block; }
  .hero-scroll-cue:hover, .hero-scroll-cue:focus-visible{ opacity:.9; }
  @keyframes hero-scroll-cue-drift{
    0%, 100%{ transform:translateX(-50%) translateY(0); }
    50%{ transform:translateX(-50%) translateY(.35rem); }
  }
  @media (prefers-reduced-motion: reduce){
    .hero-scroll-cue{ animation:none; }
  }

  /* ------------------------------------------------------------------ */
  /* STICKY NAV — hidden over the hero, fades in once it's scrolled past */
  /* ------------------------------------------------------------------ */
  .sticky-nav{
    position:fixed; top:0; left:0; right:0; z-index:40;
    display:flex; justify-content:flex-end; align-items:center;
    padding:1.1rem clamp(1.25rem,5vw,4rem);
    background:rgba(11,12,16,.72);
    backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
    border-bottom:1px solid var(--line-2);
    opacity:0; transform:translateY(-100%);
    pointer-events:none;
    transition:opacity .45s var(--ease), transform .45s var(--ease);
  }
  .sticky-nav.in{ opacity:1; transform:none; pointer-events:auto; }
  .sticky-nav a,
  .sticky-nav button{
    display:flex; align-items:baseline; gap:.55em;
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' var(--wide),'wght' 600;
    font-size:.86rem;
    color:var(--mercury);
    background:none; border:0; padding:0; cursor:pointer;
    transition:color .3s var(--ease);
  }
  .sticky-nav a .n,
  .sticky-nav button .n{
    font-family:'IBM Plex Mono', monospace; font-weight:400;
    font-size:.78em; letter-spacing:.02em; color:var(--pewter-2);
  }
  .sticky-nav a:hover, .sticky-nav a:focus-visible,
  .sticky-nav button:hover, .sticky-nav button:focus-visible{ color:var(--silver); }
  /* desktop: the four section links sit in the bar as a row. Below
     760px they collapse behind the "..." toggle into a dropdown panel —
     see the max-width:760px block below.                              */
  /* qualified with the ancestor class (not just .sticky-nav-toggle) so
     this outranks .sticky-nav button{ display:flex }, which also
     matches this element and would otherwise win on specificity        */
  .sticky-nav .sticky-nav-toggle{
    display:none; align-items:center; justify-content:center;
    width:2rem; height:2rem; margin:-.4rem 0;
    background:none; border:0; padding:0; cursor:pointer;
    color:var(--mercury); font-size:1.5rem; line-height:1;
    transition:color .3s var(--ease);
  }
  .sticky-nav-toggle:hover, .sticky-nav-toggle:focus-visible{ color:var(--silver); }
  .sticky-nav-links{
    display:flex; flex-direction:row; align-items:center;
    gap:clamp(1.5rem,3vw,2.4rem);
  }
  /* the bar is position:fixed and sits on top of the document, so jumping
     to an anchor lands its heading right underneath it — this offsets
     the scroll target by the bar's own height (plus a little breathing
     room) so the heading clears it instead of being covered.            */
  #work, #credits, #perspectives-grid, #about{ scroll-margin-top:5.5rem; }
  @media (max-width:760px){
    .sticky-nav{ padding:.85rem clamp(1.25rem,5vw,4rem); }
    /* bar is shorter on mobile (no row of links, just the toggle) */
    #work, #credits, #perspectives-grid, #about{ scroll-margin-top:4.25rem; }
    .sticky-nav .sticky-nav-toggle{ display:flex; }
    /* anchored to the bar's own right edge — .sticky-nav is position:fixed,
       so it's already the containing block for this. Full-bleed sheet
       rather than a floating card, to match phone width.                */
    .sticky-nav-links{
      display:none; flex-direction:column; align-items:stretch;
      position:absolute; top:100%; left:0; right:0;
      padding:.3rem clamp(1.25rem,5vw,4rem) .9rem;
      background:rgba(11,12,16,.94);
      backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
      border:1px solid var(--line-2); border-top:0; border-left:0; border-right:0;
    }
    .sticky-nav.open .sticky-nav-links{ display:flex; }
    .sticky-nav-links a, .sticky-nav-links button{
      justify-content:flex-end;
      padding:.75rem 0; font-size:.82rem;
      border-bottom:1px solid var(--line-2);
    }
    .sticky-nav-links a:last-child, .sticky-nav-links button:last-child{ border-bottom:0; }
    /* mirrors the desktop composition instead of scattering pieces across
       the photo's bands: wordmark+kicker stay one grouped block, same as
       the desktop brand column, dropped into the cloud bank. Nav is a
       second block, pinned by eye to just below the lower headlight on
       the switchback road rather than to a flex relationship with the
       brand — the two blocks are positioned independently.               */
    .hero-row{
      flex-direction:column; align-items:flex-start;
      justify-content:flex-start; padding-block:36vh 4vh;
    }
    .hero-media{ background-position:41% center; }
    /* sun lands in a different spot on this narrower crop — same soft
       dimmer, recentered via the same pixel-sampled source coordinates  */
    .hero-scrim{
      background:
        radial-gradient(circle at 70% 39%, rgba(6,7,10,.22) 0%, rgba(6,7,10,.1) 9%, transparent 19%),
        linear-gradient(to top, rgba(11,12,16,.5) 0%, rgba(11,12,16,.46) 2%, rgba(11,12,16,.28) 7%, rgba(11,12,16,.1) 13%, transparent 26%),
        linear-gradient(100deg, rgba(4,5,7,.31) 0%, rgba(4,5,7,.14) 36%, rgba(4,5,7,.04) 64%, rgba(4,5,7,.18) 100%),
        linear-gradient(to top, rgba(4,5,7,.36) 0%, rgba(4,5,7,.1) 30%, transparent 54%),
        linear-gradient(to bottom, rgba(4,5,7,.16) 0%, transparent 22%);
    }
    .hero-kicker{ max-width:80vw; }
    /* the numbered section links crowd the brand text on narrow screens —
       dropped here since .sticky-nav's own toggle already covers section
       navigation on mobile                                               */
    .hero-nav{ display:none; }
  }

  /* ------------------------------------------------------------------ */
  /* WORK GRID — poster wall                                            */
  /* ------------------------------------------------------------------ */
  /* Opaque so this band doesn't pick up the fixed body vignette as you
     scroll (that washing-across is what made the hero hand-off read as
     a seam). Flat --ink, matching Credits and Perspectives below it.    */
  #work{ background:var(--ink); }

  .grid{
    display:grid;
    /* don't stretch tiles to match the tallest one in a row — rows with
       an award-badge tile next to a plain one would otherwise leave the
       plain tile's box taller than its content, and Chromium's <button>
       centers its content inside that extra space (divs don't), which
       knocks the thumbnails out of alignment                           */
    align-items:start;
    grid-template-columns:repeat(auto-fill, minmax(clamp(240px, 28vw, 330px), 1fr));
    gap:clamp(2rem, 3.6vw, 3.2rem) clamp(1.5rem, 2.6vw, 2.4rem);
  }
  .tile{
    position:relative; display:block; width:100%;
    padding:0; text-align:left; font:inherit; color:inherit; background:none; border:0;
  }
  /* native <button> chrome reserves its own internal inset even with
     padding/border zeroed out — appearance:none strips it so button
     tiles align flush with the div-based ones, pixel for pixel        */
  .tile:is(button,a){ cursor:pointer; appearance:none; -webkit-appearance:none; }
  /* the cropped video frame — separate from .tile itself so the caption
     below can sit in normal flow instead of overlaying the image        */
  .tile-frame{
    position:relative; display:block; aspect-ratio:16/9;
    overflow:hidden; background:var(--ink-2);
    transition:transform .4s var(--ease);
  }
  .tile:is(button,a):hover .tile-frame,
  .tile:is(button,a):focus-visible .tile-frame{
    transform:translateY(-3px);
  }
  .tile-img{
    position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
    filter:grayscale(.3) brightness(.8) contrast(1.03);
    transition:transform .6s var(--ease), filter .5s var(--ease);
  }
  .tile:is(button,a):hover .tile-img,
  .tile:is(button,a):focus-visible .tile-img{
    transform:scale(1.05); filter:grayscale(0) brightness(.95);
  }
  /* the source still is shorter than the 16:9 frame, so a centered crop
     clips the Hulu logo sitting right at the bottom edge — pin the crop
     to the top instead so the logo always stays in frame               */
  .tile-img--bh{ object-position:center 100%; }
  .tile-info{
    display:flex; flex-direction:column; gap:.3rem;
    padding-top:.85rem;
  }
  .tile-head{
    display:flex; flex-wrap:wrap; justify-content:space-between; align-items:baseline;
    gap:.25rem 1rem;
  }
  .tile-name{
    font-size:.84rem; font-weight:500; letter-spacing:.05em;
    color:var(--mercury); text-transform:uppercase;
  }
  .tile-role{ font-size:.69rem; letter-spacing:.1em; color:var(--pewter); text-transform:uppercase; }
  .tile-meta{ font-size:.69rem; letter-spacing:.1em; color:var(--pewter); text-transform:uppercase; }
  .tile-company{ font-size:.64rem; letter-spacing:.08em; color:var(--pewter-2); text-transform:uppercase; }
  /* placeholder state for credits tiles awaiting a sourced trailer/poster */
  .tile-pending{
    position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
    text-align:center; padding:1rem;
    font-size:.64rem; letter-spacing:.12em; line-height:1.7; text-transform:uppercase;
    color:var(--pewter-2);
  }
  .tile-tag{
    margin-left:auto; text-align:right; max-width:65%;
    font-size:.66rem; letter-spacing:.12em; text-transform:uppercase; color:var(--mercury);
    white-space:normal;
  }
  /* award callout — sits as its own right-aligned line beneath the role/
     network lines (not inline with the title), in a muted brass gold
     rather than the site's usual silver/mercury. Lives directly in
     .tile-info now, so it's aligned via align-self, not margin-left:auto. */
  .tile-tag--award{
    display:flex; flex-direction:column; align-items:flex-end; align-self:flex-end;
    gap:.25rem; max-width:80%; margin-left:0; margin-top:.3rem;
  }
  .tile-tag-line{
    font-size:.64rem; letter-spacing:.11em; text-transform:uppercase;
    color:var(--gold-soft); white-space:normal;
  }
  .tile-tag-line--main{
    font-size:clamp(.72rem,1.7vw,.84rem); font-weight:600; letter-spacing:.03em;
    color:var(--gold); white-space:normal;
    text-shadow:0 0 18px rgba(201,166,103,.22);
  }
  .tile-play{
    position:absolute; top:50%; left:50%; z-index:2;
    transform:translate(-50%,-50%) scale(.9);
    width:3.4rem; height:3.4rem; border-radius:50%; display:grid; place-items:center;
    border:1px solid rgba(238,241,244,.55); color:var(--mercury);
    font-size:.9rem; padding-left:.15em;
    background:rgba(6,6,9,.3); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
    opacity:0; transition:opacity .4s var(--ease), transform .4s var(--ease);
  }
  .tile:is(button,a):hover .tile-play,
  .tile:is(button,a):focus-visible .tile-play{ opacity:1; transform:translate(-50%,-50%) scale(1); }
  @media (hover:none){
    .tile-play{ opacity:.6; }
  }
  /* type-poster tiles (no trailer artwork) */
  .tile--type{
    background:
      radial-gradient(130% 110% at 28% 0%, rgba(120,140,170,.10), transparent 58%),
      var(--ink-2);
  }
  .tile--type::after{ background:linear-gradient(to top, rgba(6,6,9,.72), rgba(6,6,9,.08)); }
  a.tile--type{ text-decoration:none; }

  /* ------------------------------------------------------------------ */
  /* PERSPECTIVES PREVIEW — in-page grid, opens the takeover below       */
  /* ------------------------------------------------------------------ */
  /* typographic treatment matched to .ab-statement on Connect — that
     section sets the tone for the site's statement lines               */
  .pv-lede{
    max-width:100%;
    margin-bottom:clamp(2rem,5vh,3.5rem);
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' 100,'wght' 420;
    font-size:clamp(1.25rem, 2.3vw, 2.2rem);
    line-height:1.2; letter-spacing:-.008em;
    color:var(--mercury);
  }
  /* statement leads, directly above the heading                        */
  #perspectives-grid .pv-lede{ margin-bottom:clamp(1.45rem,3.9vh,2.44rem); }
  /* small subtitle under the heading — tighten .sec-head's own gap so
     it reads as a caption to "Perspectives" rather than a floating line */
  #perspectives-grid .sec-head{ margin-bottom:.6rem; }
  .pv-subtitle{
    margin-bottom:clamp(1.3rem,3.25vh,2.25rem);
    font-size:.8rem; letter-spacing:.12em; text-transform:uppercase;
    color:var(--mercury); opacity:.62;
  }
  .pv-grid{
    display:grid;
    grid-template-columns:repeat(3, 1fr);
    gap:clamp(1.5rem, 2.6vw, 2.2rem) clamp(1.2rem, 2vw, 1.8rem);
  }
  @media (max-width:760px){
    .pv-grid{ grid-template-columns:repeat(2, 1fr); }
  }
  @media (max-width:520px){
    .pv-grid{ grid-template-columns:1fr; }
  }
  .pv-tile{
    position:relative; display:block; width:100%; cursor:pointer;
    padding:0; text-align:left; font:inherit; color:inherit; background:none; border:0;
  }
  .pv-tile-frame{
    position:relative; display:block; aspect-ratio:3/2;
    overflow:hidden; background:var(--ink-2);
    transition:transform .4s var(--ease);
  }
  .pv-tile:hover .pv-tile-frame,
  .pv-tile:focus-visible .pv-tile-frame{ transform:translateY(-3px); }
  .pv-tile-img{
    position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
    filter:grayscale(.3) brightness(.8) contrast(1.03);
    transition:transform .6s var(--ease), filter .5s var(--ease);
  }
  .pv-tile:hover .pv-tile-img,
  .pv-tile:focus-visible .pv-tile-img{
    transform:scale(1.05); filter:grayscale(0) brightness(.95);
  }

  /* ------------------------------------------------------------------ */
  /* PERSPECTIVES — full-screen photographic takeover                   */
  /* ------------------------------------------------------------------ */
  /* Opens in place over the page rather than routing away: photography  */
  /* is the immersive exception among the four sections.                 */
  #perspectives{
    position:fixed; inset:0; z-index:80; background:var(--ink);
    opacity:0; visibility:hidden;
    transition:opacity .55s var(--ease), visibility 0s linear .55s;
  }
  #perspectives.open{
    opacity:1; visibility:visible;
    transition:opacity .55s var(--ease);
  }

  /* the stage. Frames are contained, never cropped — the ink surround
     is part of the presentation.                                        */
  .pv-stage{ position:absolute; top:7vh; left:7vw; right:7vw; bottom:16vh; }
  .pv-shot{
    position:absolute; inset:0; width:100%; height:100%;
    object-fit:contain; object-position:center;
    opacity:0; user-select:none;
  }
  .pv-shot.enter{ animation:pvEnter .6s var(--ease) both; }
  /* the outgoing frame lingers as an afterimage — the hero's doubling
     motif carried into the transition.                                  */
  .pv-shot.ghost{ animation:pvGhost .6s var(--ease) both; pointer-events:none; }

  @keyframes pvEnter{
    from{ opacity:0; transform:translateX(calc(var(--pv-dir,1) * -1.1%)); }
    to  { opacity:1; transform:none; }
  }
  @keyframes pvGhost{
    from{ opacity:.55; transform:none; filter:blur(0); }
    to  { opacity:0; transform:translate(calc(var(--pv-dir,1) * 1.7%), 1.2%); filter:blur(3px); }
  }

  /* click zones — quiet, no chrome until you approach them */
  .pv-zone{
    position:absolute; top:0; bottom:0; width:34%; z-index:22;
    background:transparent; border:0; padding:0; cursor:pointer; color:inherit;
  }
  .pv-zone.prev{ left:0; }
  .pv-zone.next{ right:0; }
  .pv-zone .chev{
    position:absolute; top:50%; transform:translateY(-50%);
    font-family:'IBM Plex Mono', monospace; font-size:1.6rem; color:var(--pewter);
    opacity:0; transition:opacity .3s var(--ease), transform .3s var(--ease);
  }
  .pv-zone.prev .chev{ left:2.2vw; }
  .pv-zone.next .chev{ right:2.2vw; }
  @media (hover:hover){
    .pv-zone.prev:hover .chev{ opacity:1; transform:translateY(-50%) translateX(-3px); }
    .pv-zone.next:hover .chev{ opacity:1; transform:translateY(-50%) translateX(3px); }
  }
  .pv-zone:focus-visible{ outline:1px solid var(--line); outline-offset:-10px; }
  .pv-zone[aria-disabled="true"]{ cursor:default; }
  .pv-zone[aria-disabled="true"] .chev{ display:none; }

  /* meta line: just the counter, right-aligned. Sits in the same row as
     .pv-title (below) — bottom offset split the difference between the
     counter's old baseline and the title's old position under the frame  */
  .pv-meta{
    position:absolute; left:7vw; right:7vw; bottom:11vh; z-index:23;
    display:flex; justify-content:flex-end; align-items:baseline;
    pointer-events:none;
  }
  .pv-count{
    font-family:'IBM Plex Mono', monospace; font-size:.75rem; letter-spacing:.14em;
    color:var(--pewter-2); white-space:nowrap;
  }
  .pv-count b{ color:var(--silver); font-weight:400; }
  /* the photograph's title: left edge pinned in JS to the actual rendered
     image's left edge (object-fit:contain letterboxes inside .pv-stage,
     so that edge moves with each photo's aspect ratio); vertically fixed
     in the same row as .pv-count so the two align across the frame       */
  .pv-title{
    position:absolute; left:0; bottom:11vh; z-index:23;
    font-family:'IBM Plex Mono', monospace; font-size:.72rem; letter-spacing:.1em;
    color:var(--pewter); white-space:nowrap;
    pointer-events:none;
  }
  .pv-title-slash{ color:var(--pewter-2); }

  .ov-close{
    position:absolute; top:3.2vh; right:7vw; z-index:24;
    display:flex; align-items:center; gap:.7em;
    font-family:'IBM Plex Mono', monospace; font-size:.7rem;
    letter-spacing:.2em; text-transform:uppercase;
    color:var(--pewter); background:transparent; border:0; cursor:pointer; padding:.6em;
    transition:color .3s var(--ease);
  }
  .ov-close:hover, .ov-close:focus-visible{ color:var(--mercury); outline:none; }
  .ov-close .x{ font-size:1rem; line-height:1; }
  .ov-close.emphasis{ color:var(--silver); }

  @media (max-width:720px){
    .pv-stage{ top:9vh; left:4vw; right:4vw; bottom:19vh; }
    .pv-meta{ left:4vw; right:4vw; }
    .ov-close{ right:4vw; }
  }

  @media (prefers-reduced-motion: reduce){
    #perspectives{ transition:opacity .2s linear, visibility 0s linear .2s; }
    .pv-shot.enter{ animation:pvFadeIn .25s linear both; }
    .pv-shot.ghost{ animation:pvFadeOut .25s linear both; }
  }
  @keyframes pvFadeIn{ from{ opacity:0 } to{ opacity:1 } }
  @keyframes pvFadeOut{ from{ opacity:.4 } to{ opacity:0 } }

  /* ------------------------------------------------------------------ */
  /* ADDITIONAL CREDITS                                                 */
  /* ------------------------------------------------------------------ */
  .addl{ margin-top:clamp(1.4rem,3vh,2rem); }
  .addl-head{
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' var(--wide),'wght' 620;
    font-size:clamp(1.05rem, 1.8vw, 1.4rem);
    letter-spacing:.03em; text-transform:uppercase;
    color:var(--silver);
    padding-bottom:1.1rem; margin-bottom:1.4rem;
    border-bottom:1px solid var(--line);
  }
  .addl-list{ list-style:none; display:grid; gap:1.4rem; }
  .addl-list li{
    display:flex; flex-direction:column;
    border-bottom:1px solid var(--line-2); padding-bottom:1.1rem;
  }
  .addl-list li:last-child{ border-bottom:0; padding-bottom:0; }
  .addl-title{
    color:var(--silver);
    font-variation-settings:'wdth' 110,'wght' 560;
    font-size:1.05rem;
  }
  .addl-dir{
    margin-top:.35rem;
    font-size:.74rem; letter-spacing:.06em; color:var(--pewter);
  }
  .addl-meta{
    margin-top:.25rem;
    font-size:.74rem; letter-spacing:.06em; color:var(--pewter-2);
  }

  /* ------------------------------------------------------------------ */
  /* ABOUT & CONTACT                                                    */
  /* ------------------------------------------------------------------ */
  /* Follows page 2 of the sketch: ink holds the left, the portrait fills
     the right, and the statement crosses the seam between them. A full-
     bleed section on the page, same footing as .hero, rather than a
     takeover — it's the last thing you scroll to.                      */
  #about{
    position:relative; min-height:100vh; min-height:100svh; overflow:hidden;
    background:var(--ink);
  }

  /* full-bleed, so this sets its own gutter rather than using .wrap —
     the statement should start near the edge as it does in the sketch */
  /* bottom-anchored: identity + contact + colophon read as one cluster
     pinned to the base of the section, rather than centered with a big
     empty gap above and a crowded bottom — padding-bottom is the fixed
     breathing room between the colophon and the viewport edge.         */
  .ab-inner{
    position:relative; z-index:2;
    min-height:100vh; min-height:100svh;
    display:flex; flex-direction:column; justify-content:flex-end;
    padding:var(--space-md) clamp(1.5rem,5vw,4.5rem) var(--space-xl);
  }

  .ab-statement{
    max-width:min(56%, 32ch);
    font-variation-settings:'wdth' 100,'wght' 420;
    font-size:clamp(1.25rem, 2.3vw, 2.2rem);
    line-height:1.2; letter-spacing:-.008em;
    color:var(--mercury);
  }
  /* Connect's own statement line — scoped here (not on the shared
     .ab-statement rule above, which Hero's paragraph also carries) so
     the left-align and spacing don't leak onto Hero's own copy. Lifted
     off its flex position via transform (percentage is relative to the
     block's own height, same technique as .hero-brand) so it reads
     noticeably higher without disturbing the contact block below it.   */
  #about .ab-statement{
    align-self:flex-start;
    margin-bottom:var(--space-lg);
    text-align:left;
    text-wrap:balance;
    transform:translateY(-20%);
  }

  /* identity → contact: one evenly-weighted band, matching the gap
     below the contact block so the section reads as three even bands
     (identity / contact / colophon) instead of a void then a crowd     */
  .ab-contact{
    align-self:flex-end;
    margin-top:var(--space-lg);
    max-width:min(56%, 46ch);
    display:flex; flex-direction:column; gap:var(--space-xs);
  }
  /* primary contact point — prominent but no longer shouting            */
  .ab-mail{
    width:fit-content; padding-bottom:.15em;
    border-bottom:1px solid var(--pewter-2);
    font-family:'IBM Plex Mono', monospace;
    font-size:clamp(1rem,2.1vw,1.6rem); letter-spacing:.01em;
    color:var(--silver);
    transition:color .3s var(--ease), border-color .3s var(--ease);
  }
  .ab-mail:hover{ color:var(--mercury); border-color:var(--mercury); }
  /* sits below the contact links, inside .ab-contact's own flex column —
     that gap already spaces it, so no extra margin-top is needed here   */
  .ab-facts{
    display:flex; flex-wrap:wrap; justify-content:flex-start; gap:.45rem 1.5rem;
  }
  .ab-facts span{
    font-family:'Archivo', system-ui, sans-serif;
    font-variation-settings:'wdth' 100,'wght' 400;
    font-size:.88rem; letter-spacing:.005em; color:var(--silver);
  }
  /* secondary row — quieter than the email, dot-separated like the sketch */
  .ab-socials{ display:flex; flex-wrap:wrap; align-items:baseline; gap:.6rem; }
  .ab-socials a:not(:first-child){ position:relative; padding-left:.7rem; }
  .ab-socials a:not(:first-child)::before{
    content:'\00b7'; position:absolute; left:-.05rem; color:var(--pewter-2);
  }
  .ab-socials a:hover{ opacity:1; }
  /* closing row — just the copyright now (wordmark lives in the corner
     mark instead); kept right-set under the hairline, matching the
     contact block above it.                                            */
  .ab-footer{
    display:flex; justify-content:flex-end;
    /* wider gap than --space-lg on purpose — lifts the name/contact
       cluster so the email link's top edge lines up with the top of the
       headlights on the switchback road, while staying pinned to the
       base via .ab-inner's flex-end + padding-bottom                   */
    margin-top:clamp(4rem, 12.6vh, 7.5rem);
    padding-top:clamp(1.3rem,3vh,1.9rem);
    border-top:1px solid var(--line);
    max-width:100%;
  }
  .ab-copyright{
    font-family:'IBM Plex Mono', monospace; font-size:.68rem;
    letter-spacing:.06em; color:var(--pewter-2);
  }

  /* narrow: identity/contact cluster still bottom-anchored on black */
  @media (max-width:820px){
    /* the sticky nav bar is already visible by the time Connect scrolls
       into view (unlike on Hero), so its corner mark needs extra
       clearance instead of the standard --pad offset                   */
    #about .hero-corner-logo{ top:3.5rem; }
    /* bottom padding trimmed (from 9vh) to lower the whole cluster so the
       email lines up with the bottom of the lower headlight pair — the
       internal gaps between name/contact/colophon are untouched         */
    .ab-inner{ justify-content:flex-end; padding-block:14vh 4.7vh; }
    .ab-statement,
    .ab-contact,
    .ab-footer{ max-width:100%; }
    /* colophon stays pinned via .ab-inner's own padding-bottom (no room
       left there), so the extra ~2 rows of lift come from tightening
       the gap above it instead — pulls name+contact down together      */
    .ab-footer{ margin-top:3.75rem; }
    /* scaled down with the desktop email size — the floor is still wide
       enough to fit narrow phones without overflowing its column       */
    .ab-mail{ font-size:clamp(.68rem,3.4vw,1.05rem); }
    /* dropped below the desktop clamp's floor so the line breaks to two
       rows instead of three at narrow widths                            */
    #about .ab-statement{ font-size:1.125rem; }
  }

  /* ------------------------------------------------------------------ */
  /* CREDITS — now an in-page band between Selected Work and Connect,    */
  /* laid out as tiles matching the #work grid.                         */
  /* ------------------------------------------------------------------ */
  #credits{ background:var(--ink); padding-bottom:clamp(1.1rem,2.9vh,2.25rem); }

  .cr-group{ margin-bottom:clamp(3rem,7vh,4.5rem); }
  /* fixed 4-up thumbnail row (mirrors .pv-grid's pattern) — smaller than
     the auto-fill #work tiles, and doesn't grow past 4 on wide screens */
  .cr-group .grid{
    grid-template-columns:repeat(4, 1fr);
    gap:clamp(1.25rem,2.6vw,1.9rem) clamp(1rem,2vw,1.6rem);
    margin-bottom:clamp(2.5rem,6vh,4rem);
    width:92%; margin-inline:auto;
  }
  @media (max-width:900px){
    .cr-group .grid{ grid-template-columns:repeat(3, 1fr); }
  }
  @media (max-width:760px){
    .cr-group .grid{ grid-template-columns:repeat(2, 1fr); }
  }
  /* Credits posters are vertical (movie-poster proportions), unlike the
     16:9 trailer stills in #work, so this grid gets its own frame ratio.
     object-fit:contain (not cover) so every poster shows uncropped —
     the ink frame letterboxes around whatever aspect ratio it was shot at. */
  .cr-group .tile-frame{ aspect-ratio:2/3; }
  .cr-group .tile-img{ object-fit:contain; object-position:center; }

  /* ------------------------------------------------------------------ */
  /* VIDEO LIGHTBOX                                                     */
  /* ------------------------------------------------------------------ */
  .lightbox{
    position:fixed; inset:0; z-index:100; display:none;
    place-items:center; padding:var(--pad);
    background:rgba(6,6,9,.86);
    backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  }
  .lightbox.open{ display:grid; }
  .lightbox-inner{
    position:relative; width:min(1000px,100%);
    aspect-ratio:16/9; background:#000;
    border:1px solid var(--line);
    box-shadow:0 40px 120px rgba(0,0,0,.6);
    animation:pop .35s var(--ease) both;
  }
  @keyframes pop{ from{ opacity:0; transform:scale(.97) translateY(8px); } to{ opacity:1; transform:none; } }
  .lightbox-inner iframe,
  .lightbox-inner video{ position:absolute; inset:0; width:100%; height:100%; border:0; background:var(--ink-2); }
  .trailer-poster{
    position:absolute; inset:0; width:100%; height:100%;
    padding:0; border:0; cursor:pointer; background:var(--ink-2);
  }
  .trailer-poster img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
  .trailer-poster .play{
    position:absolute; top:50%; left:50%; z-index:1;
    transform:translate(-50%,-50%);
    width:4.6rem; height:4.6rem; border-radius:50%; display:grid; place-items:center;
    border:1px solid rgba(238,241,244,.55); color:var(--mercury);
    font-size:1.2rem; padding-left:.2em;
    background:rgba(6,6,9,.45); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
    transition:transform .3s var(--ease), background .3s var(--ease);
  }
  .trailer-poster:hover .play,
  .trailer-poster:focus-visible .play{ transform:translate(-50%,-50%) scale(1.08); background:rgba(6,6,9,.65); }
  .lightbox-cap{
    position:absolute; left:0; bottom:-1.9rem;
    font-family:'IBM Plex Mono', monospace; font-size:.72rem;
    letter-spacing:.12em; text-transform:uppercase; color:var(--pewter);
  }
  .lightbox-close{
    position:absolute; top:-1.1rem; right:-1.1rem; z-index:2;
    width:2.4rem; height:2.4rem; border-radius:50%;
    background:var(--ink); border:1px solid var(--line); color:var(--silver);
    font-size:1.1rem; cursor:pointer; line-height:1;
    transition:color .3s var(--ease), border-color .3s var(--ease);
  }
  .lightbox-close:hover{ color:var(--mercury); border-color:var(--mercury); }
  @media (max-width:520px){
    .lightbox-close{ top:-3rem; right:0; }
  }
  @media (prefers-reduced-motion: reduce){
    .lightbox-inner{ animation:none; }
  }
