  /* BD Plakatbau (Büro Destruct / Typedifferent.com) — user-provided font
     file, fonts/BD_Plakatbau.otf. Free-tier license: personal/non-commercial
     use is unrestricted, but the foundry's EULA (fonts/ — see the .otf's
     original zip) asks that commercial use be cleared with them first and
     that Büro Destruct be credited as the font's designer wherever design
     credits are shown. This site promotes paid photography work, so that's
     worth acting on, not just noting here. No build step needed for this —
     @font-face works directly off a local file path, unlike the Google
     Fonts families elsewhere in this project which need their own <link>
     in each page's <head>. */
  @font-face{
    font-family:'BD Plakatbau';
    src:url('fonts/BD_Plakatbau.otf') format('opentype');
    font-weight:400;
    font-style:normal;
    font-display:swap;
  }
  :root{
    --dawn-gold:#e5e1d8;
    --dawn-gold-dim:#d2cdc5;
    --dusk-ember:#d2cdc5;
    --dusk-ember-dim:#b3ada5;
    --twilight-violet:#b3ada5;
    --twilight-violet-dim:#b3ada5;
    --night-void:#b3ada5;
    --night-void-2:#b3ada5;
    --stage-cyan:#b3ada5;
    --stage-magenta:#b3ada5;
    --paper:#f4f3ef;
    --paper-glass:rgba(244,243,239,.82);
    /* was #b3ada5 — only ~2:1 contrast against --paper, well under the
       WCAG AA minimum (4.5:1) for the site's default body text color.
       This warm dark gray keeps the same desaturated family but actually
       reads (~7.7:1). */
    --ink:#4a453f;
    /* Anton stays the brand mark's own face (.brand, footer .fbrand) —
       untouched here, that's a separate identity decision from section
       headlines. */
    --font-display:'Anton', sans-serif;
    /* .sec-title ("Day", "DJ & Portraits", "In the studio"...) — user-
       provided font, see the @font-face above. Bold industrial/stencil-poster
       character, closer to the site's grunge-editorial identity than the
       Bricolage Grotesque placeholder this replaced. */
    --font-section:'BD Plakatbau', sans-serif;
    /* Cabinet Grotesk replaces Fraunces: taste-skill flags Fraunces as one
       of the two most-overused "AI creative brief" serifs, and this is a
       sans display font from its own recommended pool — closer to the
       "tech but elegant" nightlife/multimedia-creator vibe than an
       editorial serif, while still supporting italic for the same emphasis
       moves (.mini-hero-title, .sec-caption) the site already relies on */
    --font-body:'Cabinet Grotesk', sans-serif;
    /* Space Mono replaces JetBrains Mono for every label/eyebrow/timestamp
       on the site — JetBrains Mono reads as a neutral code-editor font;
       Space Mono has real character (its quirky 'a' and 'g') while staying
       just as legible at label sizes, and its slightly retro-tech feel
       still fits the nightlife/multimedia-creator identity. */
    --font-mono:'Space Mono', monospace;
    /* shared strong ease-out curve for entering/exiting UI elements — built-in
       CSS easings are too weak to feel intentional (Emil Kowalski animation
       standards); reused everywhere instead of one-off cubic-beziers */
    --ease-out-strong:cubic-bezier(.16,1,.3,1);
    /* grain texture used by .lava-mass::after. feColorMatrix desaturates
       the raw turbulence: feTurbulence generates each RGBA channel
       independently by default, so without it this is literally colored
       static — blended on top of the lava blobs that showed up as random
       hue fringing ("chromatic aberration"). Coarser/higher-octave than
       .hero-grain's own copy — bigger grain clumps with more fractal detail
       help mask the feDisplacementMap's own smooth "wave" banding instead
       of a fine, mechanically-even speckle. */
    --grain-noise-coarse-svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.35' numOctaves='4' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    --grain-dark:#1c1a17;
    --grain-mid:#57514a;
  }
  *{margin:0;padding:0;box-sizing:border-box;}
  html{scroll-behavior:smooth;}
  body{
    font-family:var(--font-body);
    background:var(--paper-glass);
    color:var(--ink);
    overflow-x:hidden;
  }
  ::selection{background:var(--stage-magenta);color:white;}

  /* ---------- lava-mass: a single, page-wide layered grunge-lava background
     — one continuous texture behind header, every content section, AND the
     footer, instead of separate per-section islands. Fixed behind the whole
     page (tattoo.html / nightlife.html / contacto.html only). Three real
     layers, in paint order:
       1. base — solid pale (var(--paper)) background-color, the same tone
          the rest of the page already sits on.
       2. .lava-mass-blobs — two heavily blurred radial-gradient blobs (dark
          near-black "hot spot", medium-dark secondary mass), each
          independently drifting via its own CSS transform keyframes. The
          whole wrapper is ALSO run through an SVG filter (#lava-filter-page,
          defined inline in each page's HTML, not in this stylesheet)
          combining an animated feTurbulence with feDisplacementMap, so the
          blob edges visibly churn and warp over time instead of sliding as
          rigid circles — this is what earns the word "lava" instead of
          "gradient".
       3. .lava-mass::after — the fine feTurbulence grain/stipple already
          used elsewhere in this file, blended on top and slowly panned via
          background-position, independent of the blob motion.
     Colors are pale base / dark blobs — matching the rest of the page's
     existing light --ink-on-paper palette, so content sections no longer
     need their own separate dark background or text-color override. ---------- */
  .lava-mass{
    position:fixed;
    inset:0;
    z-index:-1;
    overflow:hidden;
    pointer-events:none;
    background:var(--paper);
    /* base/settle state for the page-exit/page-enter flash below — same
       "ease back down" duration+curve as .hero-bg img's own settle */
    filter:brightness(1);
    transition:filter .45s ease-out;
  }
  .lava-mass-blobs{
    position:absolute;
    inset:0;
    filter:url(#lava-filter-page);
  }
  .lava-mass-blobs::before,
  .lava-mass-blobs::after{
    content:'';
    position:absolute;
    border-radius:50%;
    will-change:transform;
  }
  .lava-mass-blobs::before{
    width:90vmax;height:90vmax;
    top:-30%;left:-25%;
    filter:blur(110px);
    /* several intermediate stops instead of a single hard 0%-to-transparent
       falloff — a plain two-stop radial-gradient has a near-linear alpha
       ramp that reads as a distinct "ring" once feDisplacementMap warps it;
       staggering the falloff rate breaks that ring into a softer, more
       irregular gradient before the turbulence even touches it */
    background:radial-gradient(circle, var(--grain-dark) 0%, rgba(28,26,23,.75) 22%, rgba(28,26,23,.4) 40%, rgba(28,26,23,.12) 55%, rgba(28,26,23,0) 68%);
    animation:lava-drift-a 52s ease-in-out infinite;
  }
  .lava-mass-blobs::after{
    width:65vmax;height:65vmax;
    bottom:-20%;right:-15%;
    filter:blur(100px);
    background:radial-gradient(circle, var(--grain-mid) 0%, rgba(87,81,74,.7) 25%, rgba(87,81,74,.35) 45%, rgba(87,81,74,0) 70%);
    opacity:.85;
    animation:lava-drift-b 41s ease-in-out infinite;
  }
  @keyframes lava-drift-a{
    0%{transform:translate(0,0) scale(1);}
    22%{transform:translate(14vw,10vh) scale(1.1);}
    48%{transform:translate(6vw,22vh) scale(.94);}
    71%{transform:translate(-12vw,9vh) scale(1.06);}
    100%{transform:translate(0,0) scale(1);}
  }
  @keyframes lava-drift-b{
    0%{transform:translate(0,0) scale(1);}
    30%{transform:translate(-16vw,-12vh) scale(1.16);}
    63%{transform:translate(-7vw,-22vh) scale(.88);}
    100%{transform:translate(0,0) scale(1);}
  }
  .lava-mass::after{
    content:'';
    position:absolute;
    inset:-10%;
    pointer-events:none;
    background-image:var(--grain-noise-coarse-svg);
    background-size:130px 130px;
    /* soft-light instead of overlay: overlay pivots hard at 50% luminance
       per channel, which traced a visible ring/"wave" along the blob
       gradient's own 50%-luma contour once warped — soft-light has no such
       discontinuity but still reveals grain differently in light vs dark
       areas */
    mix-blend-mode:soft-light;
    opacity:.7;
    animation:lava-grain-pan 55s linear infinite;
  }
  @keyframes lava-grain-pan{
    from{background-position:0 0;}
    to{background-position:195px 130px;}
  }
  @media (prefers-reduced-motion: reduce){
    .lava-mass-blobs::before,
    .lava-mass-blobs::after,
    .lava-mass::after{animation:none;}
  }

  /* ---------- rail (signature element: sun-to-stage-light travel) ---------- */
  /* ---------- minimal page-opener: small type hierarchy + one wide random photo,
     replaces the old oversized section-divider title on tattoo.html/nightlife.html ---------- */
  .mini-hero{
    padding-top:140px;
    padding-bottom:60px;
  }
  .mini-hero-text{
    max-width:640px;
    margin-bottom:40px;
  }
  .mini-hero-eyebrow{
    font-family:var(--font-mono);
    font-size:12px;
    letter-spacing:.15em;
    text-transform:uppercase;
    color:var(--ink);
    opacity:.9;
    margin-bottom:16px;
  }
  .mini-hero-title{
    font-family:var(--font-body);
    font-style:italic;
    font-weight:300;
    font-size:clamp(28px,4vw,42px);
    line-height:1.25;
    margin-bottom:16px;
  }
  .mini-hero-caption{
    max-width:480px;
    font-size:15px;
    line-height:1.6;
    opacity:.8;
  }
  /* aspect-ratio lives on the wrapper, not the item: a random pick that
     turns out portrait swaps in 3 more photos as a side-by-side strip (see
     the mini-hero-media randomizer script in each page) instead of one
     vertical image stretched/cropped across the whole 21:9 band — flex:1 1 0
     on each child makes that split even whether there's 1 photo or 4. */
  .mini-hero-media{
    width:100%;
    aspect-ratio:21/9;
    display:flex;
    gap:14px;
  }
  .mini-hero-media .gallery-item{
    flex:1 1 0;
    min-width:0;
    height:100%;
    aspect-ratio:auto;
  }
  @media (max-width:640px){
    .mini-hero{padding-top:110px;}
    .mini-hero-media{aspect-ratio:4/3;}
  }

  /* ---------- bio (contacto.html only) ---------- */
  .bio{
    display:flex;
    align-items:center;
    gap:60px;
    padding-bottom:60px;
  }
  .bio-media{
    flex:0 0 34%;
  }
  .bio-photo{
    position:relative;
    aspect-ratio:4/5;
  }
  /* the jpg is the full photo, the png the same shot cut out to a
     transparent-background silhouette, stacked on top of it. Both start
     heavily blurred into an indistinct haze; hovering drops the blur on
     both at once, so the portrait reads as unlocking into focus rather than
     just "an image sharpening". */
  .bio-photo-base,
  .bio-photo-cutout{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    object-fit:cover;
    filter:blur(28px);
    transition:filter .5s var(--ease-out-strong);
    will-change:filter;
  }
  .bio-photo-base{
    z-index:1;
    /* dissolves toward the edges instead of ending in a hard photo
       rectangle — same ellipse-mask trick .hero-bg uses to blend into the
       lava field — and sits at partial opacity so it reads as a soft glow
       behind the cutout rather than a second, competing photo. Small solid
       core (15%) means almost the whole layer is already fading out. */
    -webkit-mask-image:radial-gradient(ellipse 60% 60% at 50% 42%, #000 15%, transparent 100%);
    mask-image:radial-gradient(ellipse 60% 60% at 50% 42%, #000 15%, transparent 100%);
    opacity:.7;
  }
  .bio-photo-cutout{
    z-index:2;
    /* two masks intersected: the wide radial keeps the top/sides mostly
       solid while softening the rectangle's corners, the linear one fades
       out the last stretch at the bottom so the frame's hard crop (right
       where a hand/arm gets cut off) reads as a dissolve instead of an
       edge. -webkit-mask-composite's single value covers this since
       there's only one layer being composited onto the base layer. */
    -webkit-mask-image:radial-gradient(ellipse 88% 88% at 50% 45%, #000 68%, transparent 100%), linear-gradient(to bottom, #000 62%, transparent 96%);
    mask-image:radial-gradient(ellipse 88% 88% at 50% 45%, #000 68%, transparent 100%), linear-gradient(to bottom, #000 62%, transparent 96%);
    -webkit-mask-composite:source-in;
    mask-composite:intersect;
    transform:scale(1);
    transition:filter .5s var(--ease-out-strong), transform .5s var(--ease-out-strong);
    will-change:filter, transform;
  }
  .bio-photo:hover .bio-photo-base,
  .bio-photo:hover .bio-photo-cutout{filter:blur(0);}
  /* "selection" zoom on just the sharp cutout layer on hover — the soft
     jpg backdrop stays put, so the pop reads as the subject stepping
     forward instead of the whole composition growing */
  .bio-photo:hover .bio-photo-cutout{transform:scale(1.06);}

  /* "this is juan pi" annotation: a hand-drawn-style arrow + label that
     appears alongside the blur-unlock/zoom on the same hover, instead of
     needing its own trigger. Pure CSS/SVG — no JS, no new dependency —
     the arrow's stroke draws in via stroke-dashoffset, then the arrowhead
     pops in once the line finishes, before the label itself settles in. */
  .bio-annotation{
    /* covers the photo box exactly, same as the two <img> layers — the
       arrow SVG's viewBox is 0-100 on both axes with preserveAspectRatio
       ="none", so its path coordinates ARE percentages of this box,
       independent of how big the box renders at any breakpoint (fixed the
       earlier version: a separately-sized+positioned corner group whose
       max-width cap made the arrow fall short of the face once the photo
       rendered wider than ~330px, e.g. the two-column desktop layout) */
    position:absolute;
    inset:0;
    z-index:4;
    pointer-events:none;
    opacity:0;
    transition:opacity .3s var(--ease-out-strong);
  }
  .bio-photo:hover .bio-annotation{
    opacity:1;
  }
  .bio-annotation-text{
    position:absolute;
    top:6%;
    right:6%;
    font-family:var(--font-section);
    font-weight:400;
    text-transform:uppercase;
    letter-spacing:-.005em;
    font-size:clamp(14px,1.8vw,17px);
    line-height:1;
    color:var(--ink);
    text-align:right;
    white-space:nowrap;
  }
  .bio-annotation-arrow{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    overflow:visible;
  }
  .bio-annotation-arrow path{
    fill:none;
    stroke:var(--ink);
    stroke-width:2.2;
    /* keeps the line a constant screen thickness regardless of how big the
       0-100 viewBox renders (photo box width varies a lot across
       breakpoints) — without this a stroke-width authored in viewBox units
       would scale with the box and look wildly different at each size */
    vector-effect:non-scaling-stroke;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-dasharray:100;
    stroke-dashoffset:100;
    transition:stroke-dashoffset .5s var(--ease-out-strong) .15s;
  }
  .bio-photo:hover .bio-annotation-arrow path{
    stroke-dashoffset:0;
  }
  .bio-annotation-arrow polygon{
    fill:var(--ink);
    opacity:0;
    transition:opacity .2s ease .6s;
  }
  .bio-photo:hover .bio-annotation-arrow polygon{
    opacity:1;
  }

  .bio-text{flex:1 1 0;}
  .bio-text .sec-title{margin-bottom:20px;}
  .bio-text p{
    font-size:16px;
    line-height:1.7;
    margin-bottom:18px;
    max-width:560px;
  }
  .bio-text p:last-child{margin-bottom:0;}
  .bio-cta{
    font-style:italic;
    font-weight:500;
    opacity:.9;
  }
  @media (max-width:820px){
    .bio{flex-direction:column;align-items:stretch;gap:32px;}
    .bio-media{flex:none;width:100%;max-width:320px;margin:0 auto;}
  }

  /* ---------- contacto ---------- */
  .contacto{
    min-height:70vh;
    display:flex;
    flex-direction:column;
    justify-content:center;
  }
  .contacto .sec-title{margin-bottom:24px;}

  .rail{
    position:fixed;
    right:18px;
    top:6vh;
    height:88vh;
    width:2px;
    background:linear-gradient(to bottom,
      var(--dawn-gold) 0%,
      var(--dusk-ember) 22%,
      var(--twilight-violet) 45%,
      var(--night-void) 68%,
      var(--night-void) 100%);
    z-index:60;
    opacity:0.55;
  }
  .rail-dot{
    position:absolute;
    left:50%;
    top:0%;
    width:14px;height:14px;
    border-radius:50%;
    transform:translate(-50%,-50%);
    background:var(--dawn-gold);
    box-shadow:0 0 14px 4px var(--dawn-gold);
    transition:background .4s ease, box-shadow .4s ease;
  }
  .rail-label{
    position:absolute;
    right:14px;
    font-family:var(--font-mono);
    font-size:10px;
    letter-spacing:.05em;
    color:var(--ink);
    opacity:.45;
    writing-mode:vertical-rl;
    white-space:nowrap;
  }
  @media (max-width:820px){ .rail{display:none;} }

  /* ---------- nav ---------- */
  header{
    position:fixed;top:0;left:0;right:0;
    display:flex;justify-content:space-between;align-items:center;
    padding:22px 32px;
    z-index:50;
    mix-blend-mode:difference;
  }
  .brand{
    font-family:var(--font-display);
    font-size:20px;
    letter-spacing:.04em;
    color:white;
  }
  nav a{
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:white;
    text-decoration:none;
    margin-left:24px;
    opacity:1;
    display:inline-block;
    transition:opacity .2s ease, transform 160ms var(--ease-out-strong);
  }
  nav a:hover{opacity:.5;}
  nav a:active{transform:scale(.94);}
  nav{display:flex;align-items:center;}
  @media (max-width:640px){ nav a{margin-left:14px;} }

  /* ---------- language switch: EN/ES toggle living inside header's nav, so
     it inherits the same color:white + header's mix-blend-mode:difference
     trick nav links use for automatic contrast against any background ---------- */
  .lang-switch{
    display:flex;
    align-items:center;
    gap:8px;
    margin-left:24px;
    padding-left:24px;
    border-left:1px solid rgba(255,255,255,.3);
  }
  .lang-switch button{
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    color:white;
    background:none;
    border:none;
    padding:0;
    cursor:pointer;
    opacity:.4;
    transition:opacity .2s ease, transform 160ms var(--ease-out-strong);
  }
  .lang-switch button.active{opacity:1;}
  .lang-switch button:hover{opacity:.75;}
  .lang-switch button:active{transform:scale(.9);}
  @media (max-width:640px){ .lang-switch{margin-left:14px;padding-left:14px;} }

  section{
    position:relative;
    padding:120px 8vw 100px;
    overflow:hidden;
  }

  /* ---------- hero / masthead: full-bleed monochrome photo, swapped live by
     hovering "Nightlife" / "Tattoo & Piercing" in the top nav. No copy at all
     except the giant "by juanpi" signature bottom-right. ---------- */
  .hero{
    position:relative;
    min-height:100vh;
    display:flex;
    flex-direction:column;
    justify-content:flex-end;
    overflow:hidden;
    padding-bottom:64px;
    color:var(--paper);
    /* solid, dark neutral backdrop — the lava layer is gone from this page,
       so this is what the 65%-opacity hero photo blends against instead */
    background:#141210;
  }
  .hero-bg{
    position:absolute;
    inset:0;
    z-index:2;
    overflow:hidden;
    background:var(--dawn-gold-dim);
    /* the whole photo+scrim+grain stack fades to transparent toward the
       edges, "dissolving" into the lava field behind it instead of sitting
       in a hard rectangle */
    -webkit-mask-image:radial-gradient(ellipse 78% 78% at 50% 42%, #000 56%, transparent 100%);
    mask-image:radial-gradient(ellipse 78% 78% at 50% 42%, #000 56%, transparent 100%);
    /* full-bleed (100% of the viewport), but held at 65% opacity as a whole
       — grunge treatment included — so the moving lava gradient blends
       through the photo itself rather than sitting only around its edges.
       This lives on the wrapper (not the <img>), so it stays fixed through
       every later hover-triggered image swap. */
    opacity:.65;
    will-change:opacity;
  }
  .hero-bg img{
    position:absolute;inset:0;
    width:100%;height:100%;
    object-fit:cover;
    display:block;
    /* dissolving-grunge / photocopy treatment: pushed hard toward pure
       black-and-white so midtones collapse into a graphic, almost-binary
       print rather than a normal photograph */
    filter:grayscale(1) contrast(2.2) brightness(1.1);
    transition:opacity .35s var(--ease-out-strong), filter .45s ease-out;
    will-change:opacity, filter;
  }
  /* light-flash swap: brightness spikes to near-white (masking the <img>'s
     src change), then eases back down to the normal grunge exposure once
     the new photo is in — see swapHeroImage() in index.html. */
  .hero-bg img.flash-out{
    filter:grayscale(1) contrast(1.1) brightness(7);
    /* ease-out, not ease-in: an outgoing/exiting state should still start
       moving immediately, not delay the moment being watched */
    transition:filter .22s var(--ease-out-strong);
  }
  .hero-bg img.flash-in{
    filter:grayscale(1) contrast(1.1) brightness(7);
    transition:none;
  }
  .hero-scrim{
    position:absolute;inset:0;
    background:linear-gradient(180deg, rgba(10,9,7,.1) 0%, rgba(10,9,7,.3) 58%, rgba(10,9,7,.66) 100%);
  }
  .hero-halftone{
    position:absolute;inset:0;
    background-image:radial-gradient(circle, rgba(10,9,7,.95) 34%, transparent 36%);
    background-size:5px 5px;
    opacity:.24;
    mix-blend-mode:multiply;
    pointer-events:none;
  }
  .hero-grain{
    position:absolute;inset:0;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.3' numOctaves='3' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size:110px 110px;
    opacity:.45;
    mix-blend-mode:hard-light;
    pointer-events:none;
  }
  .hero-signature{
    position:relative;
    z-index:2;
    align-self:flex-end;
    text-align:right;
    color:var(--paper);
  }
  .hero-signature-img{
    /* the real signature graphic (traspaso/logos/firma.png — a
       transparent-background brush/ink mark) replaces the typed "by
       juanpi". "screen" blend mode drops its dark tones out entirely —
       letting the photo/lava behind show straight through — while the
       saturated red ink lightens into a translucent wash on top; no
       isolation on any ancestor, so it blends against the whole stack:
       lava particles (z-index:1) behind the photo (z-index:2) behind this. */
    display:block;
    width:min(50vw, 460px);
    height:auto;
    margin-left:auto;
    mix-blend-mode:screen;
    will-change:transform;
  }
  .hero-sublinks{
    display:flex;
    justify-content:flex-end;
    align-items:baseline;
    gap:28px;
    /* firma.png carries its own generous transparent margin, so a small
       (even negative) gap here is what actually reads as "just below" the
       ink instead of visually floating away from it */
    margin-top:-6px;
    padding-right:2px;
    font-family:var(--font-mono);
    font-size:13px;
    letter-spacing:.12em;
    text-transform:uppercase;
  }
  .hero-sublink{
    color:var(--paper);
    text-decoration:none;
    border-bottom:1px solid rgba(244,243,239,.5);
    padding-bottom:3px;
    opacity:.9;
    cursor:pointer;
    display:inline-block;
    transition:opacity .2s ease, border-color .2s ease, transform 160ms var(--ease-out-strong);
  }
  .hero-sublink:hover{opacity:.6;border-color:var(--paper);}
  .hero-sublink:active{transform:scale(.94);}
  @media (max-width:640px){
    .hero{padding-bottom:40px;}
    .hero-sublinks{justify-content:flex-start;}
    .hero-signature{align-self:flex-start;text-align:left;}
  }

  /* ---------- section header pattern ---------- */
  .sec-head{
    display:flex;
    justify-content:space-between;
    align-items:flex-end;
    gap:24px;
    margin-bottom:56px;
    flex-wrap:wrap;
  }
  .timestamp{
    font-family:var(--font-mono);
    font-size:13px;
    letter-spacing:.08em;
    color:var(--ink);
    opacity:.9;
  }
  .sec-title{
    font-family:var(--font-section);
    font-weight:400;
    /* BD Plakatbau reads as designed in caps — its poster-stencil character
       is built for that, not for mixed case */
    text-transform:uppercase;
    letter-spacing:-.01em;
    font-size:clamp(40px,7vw,88px);
    line-height:.9;
  }
  .sec-caption{
    max-width:340px;
    font-size:15px;
    font-style:italic;
    font-weight:300;
    line-height:1.5;
    opacity:.85;
  }

  /* ---------- text reveal (tattoo.html / nightlife.html / contacto.html):
     same paused-then-running pattern as the gallery cascade further down —
     an IntersectionObserver in each page's <script> adds .in-view once the
     element scrolls in, gated behind html.js-ready so this degrades to
     always-visible, non-animated text if JS never runs or the user prefers
     reduced motion. Deliberately just one fade+rise, not the gallery's
     fade+float combo — copy shouldn't compete with the photos for
     attention. What makes it read as dynamic instead of flat is the
     stagger: each heading/caption/paragraph gets its own animation-delay,
     set in JS from its position among sibling text in the same container,
     so a block like eyebrow/title/caption reveals as a quick cascade
     rather than all at once. */
  html.js-ready .mini-hero-eyebrow,
  html.js-ready .mini-hero-title,
  html.js-ready .mini-hero-caption,
  html.js-ready .timestamp,
  html.js-ready .sec-title,
  html.js-ready .sec-caption,
  html.js-ready .bio-text p{
    animation-name:text-reveal-in;
    animation-duration:.7s;
    animation-timing-function:var(--ease-out-strong);
    animation-fill-mode:forwards;
    animation-play-state:paused;
  }
  html.js-ready .mini-hero-eyebrow.in-view,
  html.js-ready .mini-hero-title.in-view,
  html.js-ready .mini-hero-caption.in-view,
  html.js-ready .timestamp.in-view,
  html.js-ready .sec-title.in-view,
  html.js-ready .sec-caption.in-view,
  html.js-ready .bio-text p.in-view{
    animation-play-state:running;
  }
  @keyframes text-reveal-in{
    0%{opacity:0;translate:0 22px;}
    100%{opacity:1;translate:0 0;}
  }

  /* ---------- media block: featured grid (random pick) + horizontal scroll for the rest ---------- */
  .media-block{margin-bottom:44px;}
  .media-block:last-child{margin-bottom:0;}
  .media-block-label{
    font-family:var(--font-mono);
    font-size:12px;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--ink);
    opacity:.9;
    margin-bottom:14px;
  }
  .featured-grid{
    display:grid;
    grid-template-columns:repeat(4,1fr);
    gap:14px;
    margin-bottom:16px;
  }
  /* each slot is 3:4 or 4:3; a "stacked" slot holds two landscape panes
     stacked edge-to-edge inside a 3:4 slot so nothing gets left empty */
  .featured-slot{
    position:relative;
    display:flex;
    flex-direction:column;
    gap:8px;
  }
  .featured-slot.aspect-portrait{aspect-ratio:3/4;}
  .featured-slot.aspect-landscape{aspect-ratio:4/3;}
  .featured-slot .gallery-item{
    flex:1 1 0;
    min-height:0;
    width:100%;
    aspect-ratio:auto;
  }
  @media (max-width:980px){
    .featured-grid{grid-template-columns:repeat(2,1fr);}
  }
  @media (max-width:480px){
    .featured-grid{grid-template-columns:1fr 1fr;gap:8px;}
    .featured-slot{gap:6px;}
  }

  /* ---------- horizontal scrolling rows (object-fit:cover, no distortion) ---------- */
  .row-wrap{position:relative;}
  .hscroll{
    display:flex;
    gap:14px;
    overflow-x:auto;
    overflow-y:hidden;
    padding-bottom:12px;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:thin;
    scrollbar-color:var(--dawn-gold-dim) transparent;
    cursor:grab;
    will-change:scroll-position;
    transform:translateZ(0);
  }
  .hscroll.dragging{cursor:grabbing;}
  .hscroll::-webkit-scrollbar{height:6px;}
  .hscroll::-webkit-scrollbar-thumb{background:var(--dawn-gold-dim);border-radius:3px;}
  .hscroll::-webkit-scrollbar-track{background:transparent;}

  .gallery-item{
    position:relative;
    flex:0 0 clamp(170px,18vw,260px);
    aspect-ratio:4/3;
    overflow:hidden;
    background:var(--dawn-gold-dim);
    cursor:pointer;
    /* small, consistent radius — overflow:hidden clips the photo itself to
       match, no extra element needed. Vignette is the third (inset) shadow
       tacked onto the same box-shadow list rather than a new layer: a
       soft, wide inset darkens just the corners/edges, kept subtle since
       it runs on every thumbnail in the grid at once. Both cheap, static,
       paint-once box-shadow — no extra compositor layer beyond what the
       hover transition below already needs. */
    border-radius:6px;
    box-shadow:0 10px 26px rgba(20,15,8,.18), 0 2px 6px rgba(20,15,8,.10);
    /* vignette via mask-image instead of a shadow: an ellipse radial-gradient
       (matches .hero-bg's own mask pattern elsewhere in this file) actually
       fades the photo's own pixels to transparent toward the edges, rather
       than just tinting them darker — reads as a real soft vignette. Pure
       CSS gradient, no image to decode, cheapest possible mask source. */
    -webkit-mask-image:radial-gradient(ellipse at center, #000 72%, transparent 100%);
    mask-image:radial-gradient(ellipse at center, #000 72%, transparent 100%);
    /* only transform is animated here — box-shadow triggers paint, not just
       the compositor, and this hover fires at browsing frequency across a
       whole grid of photos, so the shadow stays fixed and the lift alone
       carries the "elevation" feeling */
    transition:transform .2s var(--ease-out-strong);
    /* opacity added alongside transform: the scroll-reveal cascade
       (gallery-fade-in, further down) animates this same element's opacity,
       so the compositor needs the hint for both properties, not just the
       hover lift's transform */
    will-change:transform, opacity;
  }
  .gallery-item:hover{
    transform:translateY(-4px) scale(1.02) translateZ(0);
    z-index:2;
  }
  .gallery-item:active{transform:translateY(-2px) scale(.98) translateZ(0);}
  .gallery-item:focus-visible{outline:2px solid var(--ink);outline-offset:3px;}
  .gallery-item img,
  .gallery-item video{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    object-fit:cover;
    display:block;
    pointer-events:none;
    transition:transform .3s var(--ease-out-strong);
    /* opacity added alongside transform: the page-exit flash (further down)
       fades these to 0 instead of blowing them out with the background */
    will-change:transform, opacity;
  }
  .gallery-item:hover img,
  .gallery-item:hover video{
    transform:scale(1.08);
  }
  /* brief tactile "press" feedback on click, before the lightbox opens */
  .gallery-item.pulsing{
    transform:scale(.95);
    transition:transform .12s ease;
    box-shadow:0 6px 14px rgba(20,15,8,.22);
  }
  .gallery-item::after{
    content:'';
    position:absolute;inset:0;
    background:linear-gradient(to top, rgba(0,0,0,.28), transparent 45%);
    opacity:0;
    transition:opacity .2s ease;
  }
  .gallery-item:hover::after{opacity:1;}

  /* ---------- gallery scroll-reveal + ambient float (tattoo.html /
     nightlife.html only). A true scroll-triggered cascade needs JS — there's
     no reliable cross-browser pure-CSS way to react to "this item just
     entered the viewport" yet (animation-timeline:view() isn't there on
     Safari/Firefox) — so each .gallery-item starts hidden and only reveals
     once an IntersectionObserver in the page's <script> adds .in-view to it,
     with a per-item transition-delay assigned there too (search "cascade
     reveal"). All of this is gated behind html.js-ready, set by a tiny
     synchronous script right after <body> (skipped entirely under
     prefers-reduced-motion): if JS never runs, .gallery-item simply falls
     back to its normal fully-visible, non-animated state instead of staying
     invisible forever.
     Reveal (fade-in) and float are two @keyframes animations on the same
     element, gated together by one animation-play-state (paused until
     .in-view, then running) — the fade plays once (animation-fill-mode:
     forwards holds its end state) and the float keeps looping after it.
     Both are declared through the longhand animation-* properties, never
     the `animation` shorthand, specifically so that a later, more specific
     rule (the nth-child ones below) can set animation-name/duration without
     silently resetting animation-play-state back to its default — the
     shorthand would reset every sub-property it doesn't mention, including
     play-state, which is exactly the property this whole gating trick
     depends on. translate/scale/rotate are the standalone CSS properties,
     not the `transform` shorthand, so none of this fights the existing
     transform-based hover/press feedback on the same elements. */
  html.js-ready .gallery-item{
    animation-play-state:paused, paused;
  }
  html.js-ready .gallery-item.in-view{
    animation-play-state:running, running;
  }
  /* four variants, each pairing its own fade-in duration with its own float
     — duration varies per photo (not a flat speed for every image) and is
     short on purpose (0.6-1.05s: fast enough that the fade doesn't linger),
     while the float keeps its own distinct resting tilt, drift direction
     and amplitude per photo. Modulus 4 here is deliberately different from
     the modulus 3 (and 5) used for the scatter offsets below, so "which way
     a photo tilts" and "how far it's nudged off-grid" never fall into the
     same repeating group. */
  html.js-ready .gallery-item:nth-child(4n+1){
    animation-name:gallery-fade-in, gallery-float-a;
    animation-duration:.75s, 11s;
    animation-timing-function:var(--ease-out-strong), ease-in-out;
    animation-iteration-count:1, infinite;
    animation-fill-mode:forwards, none;
  }
  html.js-ready .gallery-item:nth-child(4n+2){
    animation-name:gallery-fade-in, gallery-float-b;
    animation-duration:.95s, 13.5s;
    animation-timing-function:var(--ease-out-strong), ease-in-out;
    animation-iteration-count:1, infinite;
    animation-fill-mode:forwards, none;
  }
  html.js-ready .gallery-item:nth-child(4n+3){
    animation-name:gallery-fade-in, gallery-float-c;
    animation-duration:.6s, 9.5s;
    animation-timing-function:var(--ease-out-strong), ease-in-out;
    animation-iteration-count:1, infinite;
    animation-fill-mode:forwards, none;
  }
  html.js-ready .gallery-item:nth-child(4n){
    animation-name:gallery-fade-in, gallery-float-d;
    animation-duration:1.05s, 15s;
    animation-timing-function:var(--ease-out-strong), ease-in-out;
    animation-iteration-count:1, infinite;
    animation-fill-mode:forwards, none;
  }

  @keyframes gallery-fade-in{
    /* opacity front-loaded to the first ~38% of the run instead of tracking
       scale/translate the whole way — the photo snaps to fully visible
       quickly (a harder, more definite appearance) while the scale/translate
       settle keeps easing smoothly for the rest of the duration; opacity
       needs no further keyframe after 38% since it has nothing left to
       interpolate toward. */
    0%{opacity:0;scale:.82;translate:0 36px;}
    38%{opacity:1;}
    100%{scale:1;translate:0 0;}
  }
  @keyframes gallery-float-a{
    0%,100%{translate:0 0;rotate:-.55deg;}
    50%{translate:.4px -3px;rotate:-.8deg;}
  }
  @keyframes gallery-float-b{
    0%,100%{translate:0 0;rotate:.45deg;}
    50%{translate:-.4px -2.4px;rotate:.75deg;}
  }
  @keyframes gallery-float-c{
    0%,100%{translate:0 0;rotate:-.25deg;}
    50%{translate:.3px -3.6px;rotate:.15deg;}
  }
  @keyframes gallery-float-d{
    0%,100%{translate:0 0;rotate:.3deg;}
    50%{translate:-.3px -2px;rotate:-.1deg;}
  }

  /* ---------- asymmetric scatter: breaks the featured-grid's 4-column rows
     and the hscroll strip's single-line alignment, so photos read as loose,
     water-scattered debris rather than snapped to a grid. Small margin
     offsets (nth-child mod 3) plus a couple of aspect-ratio variants
     (mod 5, so it never lines up with the margin groups) on the hscroll
     rows; margin offsets only (mod 3) on the featured-grid, since that grid
     already carries portrait/landscape variety via .aspect-portrait /
     .aspect-landscape. Kept small on purpose — organic, not misaligned. */
  .hscroll{padding-top:14px;}
  .hscroll .gallery-item:nth-child(3n+2){margin-top:12px;}
  .hscroll .gallery-item:nth-child(3n){margin-top:-8px;margin-left:6px;}
  .hscroll .gallery-item:nth-child(5n+2){aspect-ratio:3/4;}
  .hscroll .gallery-item:nth-child(5n+4){aspect-ratio:1/1;}
  .featured-slot:nth-child(3n+2){margin-top:16px;}
  .featured-slot:nth-child(3n){margin-top:-10px;}

  .row-nav{
    position:absolute;top:50%;
    transform:translateY(-50%);
    width:38px;height:38px;
    display:flex;align-items:center;justify-content:center;
    border:1px solid var(--dawn-gold-dim);
    background:var(--paper-glass);
    color:var(--ink);
    font-family:var(--font-mono);
    font-size:20px;
    line-height:1;
    cursor:pointer;
    z-index:5;
    opacity:.85;
    transition:opacity .2s ease, transform 160ms var(--ease-out-strong);
  }
  .row-nav:hover{opacity:1;}
  .row-nav:active{transform:translateY(-50%) scale(.9);}
  .row-nav.prev{left:-8px;}
  .row-nav.next{right:-8px;}

  @media (max-width:640px){
    .gallery-item{flex-basis:150px;}
    .row-nav{display:none;}
  }

  /* ---------- footer client / brand logo carousel (compact, discreet) ----------
     pure-CSS keyframe loop: the track holds the logo set twice back-to-back and
     translateX's by exactly -50% of its own (content-driven) width, so the loop
     is seamless and never depends on JS measuring pixel widths before images
     have finished loading. */
  .footer-logos{
    width:100%;
    display:flex;
    flex-direction:column;
    align-items:center;
    gap:14px;
    margin-top:8px;
  }
  .footer-logos-label{
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.14em;
    text-transform:uppercase;
    opacity:.55;
  }
  .footer-logo-row-wrap{
    max-width:520px;
    width:100%;
    overflow:hidden;
    -webkit-mask-image:linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
    mask-image:linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
  }
  @keyframes footer-logo-scroll{
    from{transform:translateX(0) translateZ(0);}
    to{transform:translateX(-50%) translateZ(0);}
  }
  .footer-logo-track{
    display:flex;
    width:max-content;
    animation:footer-logo-scroll 60s linear infinite;
    will-change:transform;
  }
  .footer-logo-track:hover{animation-play-state:paused;}
  .footer-logo-row{
    display:flex;
    align-items:center;
    gap:32px;
    padding:6px 16px;
  }
  .footer-logo-item{
    flex:0 0 auto;
    height:30px;
    display:flex;align-items:center;justify-content:center;
    opacity:.5;
    filter:grayscale(1);
    box-shadow:0 4px 12px rgba(20,15,8,.14);
    transition:opacity .2s ease, filter .2s ease;
  }
  .footer-logo-item:hover{opacity:.9;filter:grayscale(0);}
  .footer-logo-item img{max-height:100%;max-width:100px;object-fit:contain;display:block;}
  @media (prefers-reduced-motion: reduce){
    .footer-logo-track{animation:none;}
    .footer-logo-row-wrap{overflow-x:auto;}
  }

  /* ---------- Instagram reminder pop-up (floating, dismissible, low-key) ---------- */
  .ig-popup{
    position:fixed;
    left:24px;bottom:24px;
    max-width:300px;
    display:flex;
    gap:14px;
    align-items:flex-start;
    padding:18px 20px;
    /* barely-there glass now — legibility no longer depends on the card
       being opaque, since the content itself auto-inverts against whatever
       shows through it (see mix-blend-mode:difference below) */
    background:rgba(244,243,239,.22);
    border-radius:16px;
    backdrop-filter:blur(20px);
    -webkit-backdrop-filter:blur(20px);
    border:1px solid rgba(244,243,239,.3);
    box-shadow:0 18px 44px rgba(20,15,8,.22);
    /* above the lightbox (200) so the Instagram nudge stays reachable even
       while a photo is open, instead of being trapped behind the backdrop */
    z-index:220;
    opacity:0;
    transform:translateY(16px);
    pointer-events:none;
    transition:opacity .28s var(--ease-out-strong), transform .28s var(--ease-out-strong);
  }
  .ig-popup.show{opacity:1;transform:translateY(0);pointer-events:auto;}
  /* every piece of content in the pop-up — icon, copy, link, close button —
     paints pure white then mix-blend-mode:difference's against whatever is
     actually behind it (page, photo, lava, logo carousel...), the same trick
     already used on the fixed header's nav. diff(white, x) = invert(x), so
     the result always reads as the backdrop's photographic negative: it can
     never land on a color close to the backdrop's own, which is what keeps
     it legible no matter what scrolls underneath the now near-transparent card. */
  .ig-popup-icon{
    flex:0 0 auto;
    width:34px;height:34px;
    display:flex;align-items:center;justify-content:center;
    border:1px solid #fff;
    border-radius:9px;
    color:#fff;
    mix-blend-mode:difference;
  }
  .ig-popup-icon svg{width:18px;height:18px;display:block;}
  .ig-popup-body{flex:1 1 auto;}
  .ig-popup-text{
    font-size:13.5px;
    font-style:italic;
    line-height:1.4;
    color:#fff;
    margin-bottom:10px;
    mix-blend-mode:difference;
  }
  .ig-popup-link{
    display:inline-flex;
    align-items:center;
    gap:6px;
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.06em;
    text-transform:uppercase;
    color:#fff;
    text-decoration:none;
    border-bottom:1px solid #fff;
    padding-bottom:2px;
    mix-blend-mode:difference;
    transition:opacity .2s ease, transform 160ms var(--ease-out-strong);
  }
  .ig-popup-link:hover{opacity:.6;}
  .ig-popup-link:active{transform:scale(.95);}
  .ig-popup-close{
    position:absolute;
    top:8px;right:10px;
    width:22px;height:22px;
    display:flex;align-items:center;justify-content:center;
    background:transparent;
    border:none;
    color:#fff;
    mix-blend-mode:difference;
    opacity:.75;
    font-size:16px;
    line-height:1;
    cursor:pointer;
    transition:opacity .2s ease, transform 160ms var(--ease-out-strong);
  }
  .ig-popup-close:hover{opacity:1;}
  .ig-popup-close:active{transform:scale(.85);}
  @media (max-width:640px){
    .ig-popup{left:16px;right:16px;bottom:16px;max-width:none;}
  }

  /* ---------- page-transition flash: reuses the exact filter recipe
     .hero-bg img.flash-out/.flash-in already use for the hover-triggered
     hero photo swap (see that block for the original), scaled up to the
     whole page instead of one image. No overlay element, no backdrop-filter
     — just a brightness ramp on whatever already serves as each page's
     background (.lava-mass on tattoo/nightlife/contacto, .hero-bg img on
     index), while any gallery photo already revealed (.in-view) fades its
     own opacity to 0 instead of blowing out with the background, so it
     dissolves rather than flashing white on top of the flash. html.page-exit
     fires on internal-link click (see the IIFE
     near the top of each page's <script>); html.page-enter is added
     synchronously before first paint on every load and removed a frame
     later, so every page arrives white and eases down — same "instant
     snap to the blown-out state, then ease back down" trick as the hero's
     own .flash-in. Cheaper than the old whip-pan panel: no new DOM node,
     no backdrop-filter, filter is compositor-friendly and this only ever
     runs once per navigation, never in a loop. */
  html.page-exit .lava-mass{
    filter:brightness(7);
    transition:filter .26s var(--ease-out-strong);
  }
  html.page-enter .lava-mass{
    filter:brightness(7);
    transition:none;
  }
  html.page-exit .hero-bg img{
    filter:grayscale(1) contrast(1.1) brightness(7);
    transition:filter .26s var(--ease-out-strong);
  }
  html.page-enter .hero-bg img{
    filter:grayscale(1) contrast(1.1) brightness(7);
    transition:none;
  }
  html.page-exit .gallery-item.in-view img,
  html.page-exit .gallery-item.in-view video{
    opacity:0;
    transition:opacity .22s var(--ease-out-strong);
  }

  /* ---------- lightbox ---------- */
  .lightbox{
    position:fixed;inset:0;
    background:rgba(10,9,7,.94);
    display:flex;align-items:center;justify-content:center;
    z-index:200;
    opacity:0;
    pointer-events:none;
    transition:opacity .25s ease;
    padding:6vh 6vw;
    /* its own compositor layer so opening/closing never forces the footer,
       its logo carousel animation, or anything else on the page to repaint */
    will-change:opacity, transform;
    transform:translateZ(0);
  }
  .lightbox.open{opacity:1;pointer-events:auto;}
  .lightbox-content{max-width:90vw;max-height:88vh;}
  .lightbox-content img,
  .lightbox-content video{
    max-width:90vw;
    max-height:88vh;
    width:auto;height:auto;
    display:block;
    box-shadow:0 20px 60px rgba(0,0,0,.5);
  }
  .lightbox-close{
    position:absolute;top:22px;right:28px;
    width:44px;height:44px;
    display:flex;align-items:center;justify-content:center;
    border:1px solid var(--dawn-gold-dim);
    background:transparent;
    color:var(--paper);
    font-size:22px;
    font-family:var(--font-mono);
    cursor:pointer;
    z-index:210;
    transition:transform 160ms var(--ease-out-strong), opacity .2s ease;
  }
  .lightbox-close:hover{opacity:.7;}
  .lightbox-close:active{transform:scale(.9);}

  /* ---------- inline contact mailbox (tattoo.html / nightlife.html) ---------- */
  .mailbox-form{
    max-width:640px;
    display:flex;
    flex-direction:column;
    gap:22px;
    margin-top:8px;
  }
  .mailbox-row{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:22px;
  }
  .mailbox-form label{
    display:flex;
    flex-direction:column;
    gap:8px;
    font-family:var(--font-mono);
    font-size:11px;
    letter-spacing:.08em;
    text-transform:uppercase;
    opacity:.9;
  }
  .mailbox-form input,
  .mailbox-form textarea{
    font-family:var(--font-body);
    font-size:15px;
    color:var(--ink);
    background:transparent;
    border:none;
    border-bottom:1px solid var(--dawn-gold-dim);
    padding:8px 2px;
    resize:vertical;
    transition:border-color .2s ease;
  }
  .mailbox-form input:focus,
  .mailbox-form textarea:focus{outline:none;border-color:var(--ink);}
  .mailbox-submit{
    align-self:flex-start;
    font-family:var(--font-mono);
    font-size:12px;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--ink);
    background:transparent;
    border:1px solid var(--ink);
    padding:14px 26px;
    cursor:pointer;
    transition:background .2s ease, color .2s ease, transform 160ms var(--ease-out-strong);
  }
  .mailbox-submit:hover{background:var(--ink);color:var(--paper);}
  .mailbox-submit:active{transform:scale(.97);}
  .mailbox-direct{
    margin-top:2px;
    font-family:var(--font-mono);
    font-size:12px;
    opacity:.9;
  }
  .mailbox-direct a{color:var(--ink);border-bottom:1px solid var(--dawn-gold-dim);}
  @media (max-width:640px){
    .mailbox-row{grid-template-columns:1fr;}
  }

  footer{
    /* no background of its own — same as every other section, this lets
       .lava-mass's texture run continuous underneath instead of the footer
       reading as a separate flat panel glued to the bottom of the page */
    color:var(--ink);
    padding:70px 8vw 40px;
    display:flex;
    flex-direction:column;
    gap:28px;
    font-family:var(--font-mono);
    font-size:12px;
    border-top:1px solid rgba(210,205,197,.4);
  }
  .footer-top{
    display:flex;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:24px;
    width:100%;
  }
  footer .fbrand{
    font-family:var(--font-display);
    font-size:22px;
    color:var(--ink);
    margin-bottom:8px;
  }
  footer a{color:var(--ink);}
