/* =============================================================================
   gabrielasmar.com — site stylesheet
   -----------------------------------------------------------------------------
   One stylesheet for every page. Load it once per page from <head>:
       <link rel="stylesheet" href="assets/css/site.css">

   How this file is organised (search for the numbered headings):
       01  Design tokens        — every colour lives here, nowhere else
       02  Light theme          — automatic (browser preference) + manual override
       03  Reset and base
       04  Utilities
       05  Background layers    — gradient, bloom, stars
       06  Page shell
       07  Header, bar and menu
       08  Buttons
       09  Cards
       10  Home page
       11  Page titles
       12  Projects grid
       13  Photography gallery
       14  Project post (article + sidebar)
       15  Footer
       16  Keyframes
       17  Reduced motion

   Rules of thumb when editing:
     - Change a colour once, in section 01, and it updates across the whole site.
     - Breakpoints are mobile-first: the base rules ARE the phone layout, and
       @media (min-width: …) blocks add columns as the screen grows.
   ============================================================================= */


/* -----------------------------------------------------------------------------
   01  DESIGN TOKENS  (dark theme is the default)
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces and text */
  --ground: #0F0F13;                        /* page background */
  --ink: #F7F4EE;                           /* primary text */
  --muted: #D2CDC5;                         /* secondary text */
  --hair: rgba(247, 244, 238, 0.28);        /* hairline rules */
  --card: rgba(12, 12, 17, 0.62);           /* frosted card fill */
  --bar: rgba(12, 12, 17, 0.88);            /* header bar + menu fill (more opaque) */
  --cardline: rgba(247, 244, 238, 0.22);    /* card borders */
  --hover: rgba(247, 244, 238, 0.12);       /* hover wash on ghost controls */

  /* Background treatment */
  --scrim: rgba(8, 8, 12, 0.62);            /* darkening overlay, top and bottom */
  --scrim-mid: rgba(8, 8, 12, 0.24);        /* darkening overlay, middle */
  --stars: 0.9;                             /* starfield opacity (0 hides it) */
  --stars-dim: 0.3;                         /* starfield opacity at the twinkle trough */

  /* Gradient ramp, left to right. Also colours the pipeline dots. */
  --g1: #3F5BF7;
  --g2: #5B4CF2;
  --g3: #7A42EC;
  --g4: #9B3AE2;
  --g5: #C93BC9;

  /* Type */
  --sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
  --display: var(--sans);                   /* display face; swap here to add a second family */

  /* Motion switch. Set to "paused" to freeze every ambient animation. */
  --motion: running;

  /* Shared shadows */
  --shadow-card: 0 24px 70px rgba(0, 0, 0, 0.38);
  --shadow-bar: 0 18px 46px rgba(0, 0, 0, 0.30);
}


/* -----------------------------------------------------------------------------
   02  LIGHT THEME
   Two ways in, in this order:
     a) the visitor's browser is set to light and they have not chosen otherwise
     b) they pressed the theme button, which sets <html data-theme="light">
   assets/js/site.js writes data-theme; with JavaScript off, (a) still works.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --ground: #FBF9F4;
    --ink: #141417;
    --muted: #43403B;
    --hair: rgba(20, 20, 23, 0.26);
    --card: rgba(255, 255, 255, 0.74);
    --bar: rgba(255, 255, 255, 0.92);
    --cardline: rgba(20, 20, 23, 0.16);
    --hover: rgba(20, 20, 23, 0.07);
    --scrim: rgba(255, 255, 255, 0.68);
    --scrim-mid: rgba(255, 255, 255, 0.34);
    --stars: 0;                              /* stars read as dust on a light page */
    --stars-dim: 0;
    color-scheme: light;
  }
}
:root[data-theme="light"] {
  --ground: #FBF9F4;
  --ink: #141417;
  --muted: #43403B;
  --hair: rgba(20, 20, 23, 0.26);
  --card: rgba(255, 255, 255, 0.74);
  --bar: rgba(255, 255, 255, 0.92);
  --cardline: rgba(20, 20, 23, 0.16);
  --hover: rgba(20, 20, 23, 0.07);
  --scrim: rgba(255, 255, 255, 0.68);
  --scrim-mid: rgba(255, 255, 255, 0.34);
  --stars: 0;
  --stars-dim: 0;
  color-scheme: light;
}
:root[data-theme="dark"] { color-scheme: dark; }


/* -----------------------------------------------------------------------------
   03  RESET AND BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, figure { margin: 0; }

a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--hair); }
a:hover { color: var(--g5); border-bottom-color: var(--g5); }

button { font: inherit; color: inherit; }

img { max-width: 100%; }

/* One consistent focus ring for every interactive element. */
:focus-visible { outline: 2px solid var(--g5); outline-offset: 3px; border-radius: 4px; }


/* -----------------------------------------------------------------------------
   04  UTILITIES
   -------------------------------------------------------------------------- */

/* Keyboard-only shortcut past the header. First thing in the tab order. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 20;
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px;
  border: 1px solid var(--cardline); border-radius: 999px;
  background: var(--ground); color: var(--ink);
  font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 12px; }

/* Read by screen readers, invisible on screen. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The frosted-glass treatment shared by cards, the bar and the menu panel.
   Add class="frosted" to any panel that should sit on blurred background. */
.frosted {
  backdrop-filter: blur(22px) saturate(1.25);
  -webkit-backdrop-filter: blur(22px) saturate(1.25);
}

/* In-page links (#top, the skip link) glide instead of jumping, and stop clear
   of the sticky header rather than underneath it. */
html { scroll-behavior: smooth; scroll-padding-top: 96px; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }


/* -----------------------------------------------------------------------------
   05  BACKGROUND LAYERS
   Six fixed, pointer-transparent layers behind the page, painted in source
   order: flow -> bloom -> vignette -> scrim -> nebula -> stars.
   They live inside .bg, which every page includes verbatim.
   -------------------------------------------------------------------------- */
.bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.bg > * { position: absolute; inset: 0; }

/* Wide colour ramp that drifts sideways forever. */
.bg__flow {
  background: linear-gradient(104deg,
    var(--g1) 0%, var(--g2) 12%, var(--g3) 26%, var(--g4) 40%, var(--g5) 50%,
    var(--g4) 60%, var(--g3) 74%, var(--g2) 88%, var(--g1) 100%);
  background-size: 320% 100%;
  opacity: 0.92;
  animation: flow 75s linear infinite;
  animation-play-state: var(--motion);
}

/* Two soft blooms that breathe in and out, adding depth to the ramp. */
.bg__bloom {
  background:
    radial-gradient(100% 80% at 24% 16%, var(--g5), transparent 72%),
    radial-gradient(95% 75% at 80% 90%, var(--g4), transparent 72%);
  background-repeat: no-repeat, no-repeat;
  opacity: 0.34;
  mix-blend-mode: screen;
  animation: breathe 34s ease-in-out infinite;
  animation-play-state: var(--motion);
}

/* Darkens the edges so content in the middle stays legible. */
.bg__vignette { background: radial-gradient(135% 105% at 50% 52%, transparent 10%, var(--ground) 94%); }

/* Top-to-bottom darkening pass; carries the contrast for body copy. */
.bg__scrim { background: linear-gradient(to bottom, var(--scrim), var(--scrim-mid) 42%, var(--scrim)); }

/* Faint cloud behind the stars, top-right only. */
.bg__nebula {
  opacity: var(--stars);
  background:
    radial-gradient(58% 42% at 88% 6%, rgba(180, 140, 255, 0.20), transparent 70%),
    radial-gradient(38% 30% at 72% 14%, rgba(120, 170, 255, 0.14), transparent 72%);
  mix-blend-mode: screen;
}

/* Starfield: two layers of dots, each masked so the density falls away from the
   top-right corner. The dot positions are one long generated gradient list — to
   move the field, edit the mask rather than the dots. */
.bg__stars { opacity: var(--stars); background-image: radial-gradient(circle at 47.29% 36.86%, rgba(255,255,255,0.62) 0 0.99px, rgba(255,255,255,0) 2.19px), radial-gradient(circle at 21.98% 76.61%, rgba(255,255,255,0.94) 0 1.50px, rgba(255,255,255,0) 2.70px), radial-gradient(circle at 12.21% 51.85%, rgba(255,255,255,0.71) 0 1.43px, rgba(255,255,255,0) 2.63px), radial-gradient(circle at 34.77% 18.11%, rgba(255,255,255,0.82) 0 1.49px, rgba(255,255,255,0) 2.69px), radial-gradient(circle at 69.65% 14.79%, rgba(255,255,255,0.97) 0 0.95px, rgba(255,255,255,0) 2.15px), radial-gradient(circle at 76.28% 15.62%, rgba(255,255,255,0.63) 0 1.45px, rgba(255,255,255,0) 2.65px), radial-gradient(circle at 99.56% 2.23%, rgba(255,255,255,0.73) 0 1.37px, rgba(255,255,255,0) 2.57px), radial-gradient(circle at 32.54% 72.47%, rgba(255,255,255,0.84) 0 1.42px, rgba(255,255,255,0) 2.62px), radial-gradient(circle at 81.70% 16.43%, rgba(255,255,255,0.65) 0 1.32px, rgba(255,255,255,0) 2.52px), radial-gradient(circle at 26.04% 76.00%, rgba(255,255,255,0.82) 0 1.46px, rgba(255,255,255,0) 2.66px), radial-gradient(circle at 33.71% 4.34%, rgba(255,255,255,0.87) 0 1.43px, rgba(255,255,255,0) 2.63px), radial-gradient(circle at 65.11% 52.44%, rgba(255,255,255,0.59) 0 1.20px, rgba(255,255,255,0) 2.40px), radial-gradient(circle at 19.82% 98.65%, rgba(255,255,255,0.83) 0 0.98px, rgba(255,255,255,0) 2.18px), radial-gradient(circle at 99.42% 31.59%, rgba(255,255,255,0.62) 0 1.50px, rgba(255,255,255,0) 2.70px), radial-gradient(circle at 82.96% 0.31%, rgba(255,255,255,0.91) 0 1.02px, rgba(255,255,255,0) 2.22px), radial-gradient(circle at 28.27% 11.03%, rgba(255,255,255,0.75) 0 1.55px, rgba(255,255,255,0) 2.75px), radial-gradient(circle at 16.73% 47.47%, rgba(255,255,255,0.80) 0 1.11px, rgba(255,255,255,0) 2.31px), radial-gradient(circle at 38.49% 41.24%, rgba(255,255,255,0.57) 0 1.45px, rgba(255,255,255,0) 2.65px), radial-gradient(circle at 72.78% 12.92%, rgba(255,255,255,0.73) 0 1.34px, rgba(255,255,255,0) 2.54px), radial-gradient(circle at 51.58% 23.16%, rgba(255,255,255,0.78) 0 1.40px, rgba(255,255,255,0) 2.60px), radial-gradient(circle at 97.85% 4.73%, rgba(255,255,255,0.78) 0 1.17px, rgba(255,255,255,0) 2.37px), radial-gradient(circle at 3.56% 9.44%, rgba(255,255,255,0.74) 0 1.58px, rgba(255,255,255,0) 2.78px), radial-gradient(circle at 91.29% 16.43%, rgba(255,255,255,0.76) 0 1.24px, rgba(255,255,255,0) 2.44px), radial-gradient(circle at 99.96% 3.46%, rgba(255,255,255,0.87) 0 1.24px, rgba(255,255,255,0) 2.44px), radial-gradient(circle at 96.09% 96.65%, rgba(255,255,255,0.87) 0 1.06px, rgba(255,255,255,0) 2.26px), radial-gradient(circle at 43.93% 14.10%, rgba(255,255,255,0.93) 0 1.10px, rgba(255,255,255,0) 2.30px), radial-gradient(circle at 53.03% 1.64%, rgba(255,255,255,0.78) 0 0.96px, rgba(255,255,255,0) 2.16px), radial-gradient(circle at 48.22% 16.39%, rgba(255,255,255,0.85) 0 1.25px, rgba(255,255,255,0) 2.45px), radial-gradient(circle at 45.79% 5.91%, rgba(255,255,255,0.86) 0 1.20px, rgba(255,255,255,0) 2.40px), radial-gradient(circle at 62.13% 42.59%, rgba(255,255,255,0.69) 0 1.29px, rgba(255,255,255,0) 2.49px), radial-gradient(circle at 72.65% 34.41%, rgba(255,255,255,0.63) 0 1.23px, rgba(255,255,255,0) 2.43px), radial-gradient(circle at 6.63% 5.38%, rgba(255,255,255,0.85) 0 1.59px, rgba(255,255,255,0) 2.79px), radial-gradient(circle at 14.64% 8.36%, rgba(255,255,255,0.78) 0 1.14px, rgba(255,255,255,0) 2.34px), radial-gradient(circle at 13.12% 73.20%, rgba(255,255,255,0.56) 0 1.54px, rgba(255,255,255,0) 2.74px), radial-gradient(circle at 41.93% 51.04%, rgba(255,255,255,0.87) 0 1.35px, rgba(255,255,255,0) 2.55px), radial-gradient(circle at 15.74% 53.07%, rgba(255,255,255,0.82) 0 1.34px, rgba(255,255,255,0) 2.54px), radial-gradient(circle at 66.12% 24.43%, rgba(255,255,255,0.65) 0 0.95px, rgba(255,255,255,0) 2.15px), radial-gradient(circle at 10.52% 72.65%, rgba(255,255,255,0.66) 0 1.09px, rgba(255,255,255,0) 2.29px), radial-gradient(circle at 82.52% 56.24%, rgba(255,255,255,0.61) 0 1.38px, rgba(255,255,255,0) 2.58px), radial-gradient(circle at 93.90% 87.98%, rgba(255,255,255,0.67) 0 1.47px, rgba(255,255,255,0) 2.67px), radial-gradient(circle at 48.09% 90.03%, rgba(255,255,255,0.70) 0 1.32px, rgba(255,255,255,0) 2.52px), radial-gradient(circle at 23.21% 1.87%, rgba(255,255,255,0.80) 0 1.07px, rgba(255,255,255,0) 2.27px), radial-gradient(circle at 98.70% 23.86%, rgba(255,255,255,0.96) 0 1.04px, rgba(255,255,255,0) 2.24px), radial-gradient(circle at 69.38% 55.05%, rgba(255,255,255,0.91) 0 1.58px, rgba(255,255,255,0) 2.78px), radial-gradient(circle at 1.55% 56.45%, rgba(255,255,255,0.55) 0 1.27px, rgba(255,255,255,0) 2.47px), radial-gradient(circle at 99.77% 43.25%, rgba(255,255,255,0.92) 0 0.92px, rgba(255,255,255,0) 2.12px), radial-gradient(circle at 67.58% 80.24%, rgba(255,255,255,0.72) 0 1.40px, rgba(255,255,255,0) 2.60px), radial-gradient(circle at 97.00% 16.50%, rgba(255,255,255,0.88) 0 1.38px, rgba(255,255,255,0) 2.58px), radial-gradient(circle at 37.76% 54.92%, rgba(255,255,255,0.80) 0 1.26px, rgba(255,255,255,0) 2.46px), radial-gradient(circle at 96.53% 94.47%, rgba(255,255,255,0.77) 0 1.58px, rgba(255,255,255,0) 2.78px), radial-gradient(circle at 95.31% 23.64%, rgba(255,255,255,0.57) 0 0.99px, rgba(255,255,255,0) 2.19px), radial-gradient(circle at 96.74% 2.76%, rgba(255,255,255,0.65) 0 1.00px, rgba(255,255,255,0) 2.20px), radial-gradient(circle at 14.15% 99.82%, rgba(255,255,255,0.77) 0 1.21px, rgba(255,255,255,0) 2.41px), radial-gradient(circle at 32.19% 29.01%, rgba(255,255,255,0.79) 0 1.41px, rgba(255,255,255,0) 2.61px), radial-gradient(circle at 59.25% 60.86%, rgba(255,255,255,0.63) 0 1.58px, rgba(255,255,255,0) 2.78px), radial-gradient(circle at 86.95% 74.60%, rgba(255,255,255,0.94) 0 1.31px, rgba(255,255,255,0) 2.51px), radial-gradient(circle at 80.24% 43.96%, rgba(255,255,255,0.85) 0 1.13px, rgba(255,255,255,0) 2.33px), radial-gradient(circle at 94.32% 76.12%, rgba(255,255,255,0.91) 0 1.50px, rgba(255,255,255,0) 2.70px), radial-gradient(circle at 26.77% 83.00%, rgba(255,255,255,0.63) 0 0.96px, rgba(255,255,255,0) 2.16px), radial-gradient(circle at 51.97% 39.17%, rgba(255,255,255,0.76) 0 1.38px, rgba(255,255,255,0) 2.58px), radial-gradient(circle at 71.88% 8.88%, rgba(255,255,255,0.64) 0 1.01px, rgba(255,255,255,0) 2.21px), radial-gradient(circle at 23.47% 61.89%, rgba(255,255,255,0.56) 0 0.93px, rgba(255,255,255,0) 2.13px), radial-gradient(circle at 13.60% 66.84%, rgba(255,255,255,0.84) 0 1.24px, rgba(255,255,255,0) 2.44px), radial-gradient(circle at 43.78% 52.01%, rgba(255,255,255,0.92) 0 1.21px, rgba(255,255,255,0) 2.41px), radial-gradient(circle at 21.95% 82.20%, rgba(255,255,255,0.74) 0 1.27px, rgba(255,255,255,0) 2.47px), radial-gradient(circle at 72.49% 59.60%, rgba(255,255,255,0.76) 0 1.13px, rgba(255,255,255,0) 2.33px), radial-gradient(circle at 50.63% 79.07%, rgba(255,255,255,0.57) 0 1.08px, rgba(255,255,255,0) 2.28px), radial-gradient(circle at 73.88% 8.36%, rgba(255,255,255,0.59) 0 1.15px, rgba(255,255,255,0) 2.35px), radial-gradient(circle at 96.73% 82.28%, rgba(255,255,255,0.73) 0 1.35px, rgba(255,255,255,0) 2.55px), radial-gradient(circle at 26.46% 0.11%, rgba(255,255,255,0.98) 0 1.54px, rgba(255,255,255,0) 2.74px), radial-gradient(circle at 96.74% 62.16%, rgba(255,255,255,1.00) 0 0.91px, rgba(255,255,255,0) 2.11px), radial-gradient(circle at 95.70% 13.72%, rgba(255,255,255,0.84) 0 0.98px, rgba(255,255,255,0) 2.18px), radial-gradient(circle at 12.69% 30.75%, rgba(255,255,255,0.59) 0 0.92px, rgba(255,255,255,0) 2.12px), radial-gradient(circle at 94.68% 9.69%, rgba(255,255,255,0.61) 0 1.27px, rgba(255,255,255,0) 2.47px), radial-gradient(circle at 93.51% 2.75%, rgba(255,255,255,0.68) 0 1.18px, rgba(255,255,255,0) 2.38px), radial-gradient(circle at 96.97% 34.83%, rgba(255,255,255,0.74) 0 1.41px, rgba(255,255,255,0) 2.61px), radial-gradient(circle at 86.42% 63.58%, rgba(255,255,255,0.75) 0 1.37px, rgba(255,255,255,0) 2.57px), radial-gradient(circle at 73.58% 61.50%, rgba(255,255,255,0.66) 0 1.25px, rgba(255,255,255,0) 2.45px), radial-gradient(circle at 99.50% 43.47%, rgba(255,255,255,0.76) 0 1.04px, rgba(255,255,255,0) 2.24px), radial-gradient(circle at 13.90% 64.68%, rgba(255,255,255,0.65) 0 1.24px, rgba(255,255,255,0) 2.44px), radial-gradient(circle at 51.44% 13.99%, rgba(255,255,255,0.88) 0 1.40px, rgba(255,255,255,0) 2.60px), radial-gradient(circle at 20.87% 7.88%, rgba(255,255,255,0.92) 0 1.51px, rgba(255,255,255,0) 2.71px), radial-gradient(circle at 97.36% 39.35%, rgba(255,255,255,0.60) 0 1.10px, rgba(255,255,255,0) 2.30px), radial-gradient(circle at 87.52% 74.22%, rgba(255,255,255,0.87) 0 1.15px, rgba(255,255,255,0) 2.35px), radial-gradient(circle at 76.91% 37.06%, rgba(255,255,255,0.72) 0 1.22px, rgba(255,255,255,0) 2.42px), radial-gradient(circle at 54.67% 26.75%, rgba(255,255,255,0.79) 0 1.01px, rgba(255,255,255,0) 2.21px), radial-gradient(circle at 83.50% 28.32%, rgba(255,255,255,0.93) 0 1.46px, rgba(255,255,255,0) 2.66px), radial-gradient(circle at 70.32% 73.13%, rgba(255,255,255,1.00) 0 0.91px, rgba(255,255,255,0) 2.11px), radial-gradient(circle at 92.82% 98.57%, rgba(255,255,255,0.67) 0 1.49px, rgba(255,255,255,0) 2.69px), radial-gradient(circle at 67.29% 76.18%, rgba(255,255,255,0.69) 0 1.44px, rgba(255,255,255,0) 2.64px), radial-gradient(circle at 73.81% 43.79%, rgba(255,255,255,0.78) 0 1.15px, rgba(255,255,255,0) 2.35px), radial-gradient(circle at 58.57% 91.77%, rgba(255,255,255,0.83) 0 1.53px, rgba(255,255,255,0) 2.73px), radial-gradient(circle at 64.11% 11.06%, rgba(255,255,255,0.66) 0 1.14px, rgba(255,255,255,0) 2.34px), radial-gradient(circle at 59.13% 54.96%, rgba(255,255,255,0.65) 0 1.11px, rgba(255,255,255,0) 2.31px), radial-gradient(circle at 14.69% 36.19%, rgba(255,255,255,0.92) 0 1.04px, rgba(255,255,255,0) 2.24px), radial-gradient(circle at 22.65% 84.03%, rgba(255,255,255,0.68) 0 1.01px, rgba(255,255,255,0) 2.21px), radial-gradient(circle at 50.96% 65.11%, rgba(255,255,255,0.62) 0 1.37px, rgba(255,255,255,0) 2.57px), radial-gradient(circle at 50.49% 13.09%, rgba(255,255,255,0.73) 0 1.21px, rgba(255,255,255,0) 2.41px), radial-gradient(circle at 20.94% 95.90%, rgba(255,255,255,1.00) 0 1.35px, rgba(255,255,255,0) 2.55px), radial-gradient(circle at 82.42% 38.99%, rgba(255,255,255,0.93) 0 0.90px, rgba(255,255,255,0) 2.10px), radial-gradient(circle at 49.77% 16.08%, rgba(255,255,255,0.88) 0 1.02px, rgba(255,255,255,0) 2.22px), radial-gradient(circle at 96.73% 78.15%, rgba(255,255,255,0.87) 0 1.50px, rgba(255,255,255,0) 2.70px), radial-gradient(circle at 87.89% 0.53%, rgba(255,255,255,0.62) 0 1.25px, rgba(255,255,255,0) 2.45px), radial-gradient(circle at 68.20% 80.90%, rgba(255,255,255,0.80) 0 1.47px, rgba(255,255,255,0) 2.67px), radial-gradient(circle at 67.27% 10.54%, rgba(255,255,255,0.78) 0 1.59px, rgba(255,255,255,0) 2.79px), radial-gradient(circle at 99.38% 25.21%, rgba(255,255,255,0.93) 0 1.15px, rgba(255,255,255,0) 2.35px), radial-gradient(circle at 87.51% 0.25%, rgba(255,255,255,0.71) 0 0.98px, rgba(255,255,255,0) 2.18px), radial-gradient(circle at 39.50% 58.22%, rgba(255,255,255,0.73) 0 0.91px, rgba(255,255,255,0) 2.11px), radial-gradient(circle at 99.93% 7.55%, rgba(255,255,255,0.73) 0 1.29px, rgba(255,255,255,0) 2.49px), radial-gradient(circle at 62.27% 12.51%, rgba(255,255,255,0.94) 0 1.37px, rgba(255,255,255,0) 2.57px), radial-gradient(circle at 96.58% 21.69%, rgba(255,255,255,0.76) 0 1.40px, rgba(255,255,255,0) 2.60px), radial-gradient(circle at 63.38% 4.11%, rgba(255,255,255,0.60) 0 0.90px, rgba(255,255,255,0) 2.10px), radial-gradient(circle at 80.79% 57.65%, rgba(255,255,255,0.93) 0 1.14px, rgba(255,255,255,0) 2.34px), radial-gradient(circle at 17.50% 64.38%, rgba(255,255,255,0.86) 0 1.56px, rgba(255,255,255,0) 2.76px), radial-gradient(circle at 21.25% 4.09%, rgba(255,255,255,0.88) 0 0.92px, rgba(255,255,255,0) 2.12px), radial-gradient(circle at 8.19% 29.83%, rgba(255,255,255,0.93) 0 1.09px, rgba(255,255,255,0) 2.29px), radial-gradient(circle at 95.73% 74.02%, rgba(255,255,255,0.73) 0 1.00px, rgba(255,255,255,0) 2.20px), radial-gradient(circle at 88.09% 42.19%, rgba(255,255,255,0.69) 0 1.24px, rgba(255,255,255,0) 2.44px), radial-gradient(circle at 25.37% 63.95%, rgba(255,255,255,0.81) 0 1.43px, rgba(255,255,255,0) 2.63px), radial-gradient(circle at 87.51% 19.10%, rgba(255,255,255,0.97) 0 0.98px, rgba(255,255,255,0) 2.18px), radial-gradient(circle at 81.46% 34.45%, rgba(255,255,255,0.71) 0 1.36px, rgba(255,255,255,0) 2.56px), radial-gradient(circle at 9.71% 62.31%, rgba(255,255,255,0.96) 0 1.58px, rgba(255,255,255,0) 2.78px), radial-gradient(circle at 70.75% 59.09%, rgba(255,255,255,0.88) 0 1.26px, rgba(255,255,255,0) 2.46px), radial-gradient(circle at 35.11% 42.35%, rgba(255,255,255,0.98) 0 1.22px, rgba(255,255,255,0) 2.42px), radial-gradient(circle at 32.81% 27.10%, rgba(255,255,255,0.78) 0 1.38px, rgba(255,255,255,0) 2.58px), radial-gradient(circle at 79.57% 60.59%, rgba(255,255,255,0.85) 0 1.42px, rgba(255,255,255,0) 2.62px), radial-gradient(circle at 93.47% 46.20%, rgba(255,255,255,0.90) 0 1.27px, rgba(255,255,255,0) 2.47px), radial-gradient(circle at 67.94% 2.35%, rgba(255,255,255,0.75) 0 1.28px, rgba(255,255,255,0) 2.48px), radial-gradient(circle at 66.13% 74.11%, rgba(255,255,255,0.85) 0 1.26px, rgba(255,255,255,0) 2.46px), radial-gradient(circle at 100.00% 10.39%, rgba(255,255,255,0.93) 0 1.21px, rgba(255,255,255,0) 2.41px), radial-gradient(circle at 26.93% 77.03%, rgba(255,255,255,0.62) 0 0.97px, rgba(255,255,255,0) 2.17px), radial-gradient(circle at 98.79% 38.43%, rgba(255,255,255,0.58) 0 1.09px, rgba(255,255,255,0) 2.29px), radial-gradient(circle at 91.57% 30.11%, rgba(255,255,255,0.89) 0 0.96px, rgba(255,255,255,0) 2.16px), radial-gradient(circle at 75.20% 56.30%, rgba(255,255,255,0.82) 0 1.01px, rgba(255,255,255,0) 2.21px), radial-gradient(circle at 34.20% 2.39%, rgba(255,255,255,0.90) 0 1.40px, rgba(255,255,255,0) 2.60px), radial-gradient(circle at 42.74% 72.70%, rgba(255,255,255,0.82) 0 1.00px, rgba(255,255,255,0) 2.20px), radial-gradient(circle at 72.63% 47.98%, rgba(255,255,255,0.81) 0 1.01px, rgba(255,255,255,0) 2.21px), radial-gradient(circle at 78.37% 56.75%, rgba(255,255,255,0.60) 0 1.53px, rgba(255,255,255,0) 2.73px), radial-gradient(circle at 31.92% 49.26%, rgba(255,255,255,0.88) 0 1.22px, rgba(255,255,255,0) 2.42px), radial-gradient(circle at 30.64% 78.73%, rgba(255,255,255,0.92) 0 1.11px, rgba(255,255,255,0) 2.31px), radial-gradient(circle at 92.72% 1.41%, rgba(255,255,255,0.56) 0 1.04px, rgba(255,255,255,0) 2.24px), radial-gradient(circle at 35.16% 52.08%, rgba(255,255,255,0.93) 0 1.54px, rgba(255,255,255,0) 2.74px), radial-gradient(circle at 49.77% 35.17%, rgba(255,255,255,0.88) 0 1.47px, rgba(255,255,255,0) 2.67px), radial-gradient(circle at 73.18% 41.67%, rgba(255,255,255,0.88) 0 1.33px, rgba(255,255,255,0) 2.53px), radial-gradient(circle at 95.31% 25.76%, rgba(255,255,255,0.68) 0 0.93px, rgba(255,255,255,0) 2.13px), radial-gradient(circle at 42.14% 70.27%, rgba(255,255,255,0.96) 0 1.44px, rgba(255,255,255,0) 2.64px), radial-gradient(circle at 92.28% 28.01%, rgba(255,255,255,0.88) 0 0.97px, rgba(255,255,255,0) 2.17px), radial-gradient(circle at 91.27% 50.05%, rgba(255,255,255,0.84) 0 1.07px, rgba(255,255,255,0) 2.27px), radial-gradient(circle at 10.72% 81.35%, rgba(255,255,255,0.80) 0 0.92px, rgba(255,255,255,0) 2.12px), radial-gradient(circle at 91.14% 45.42%, rgba(255,255,255,0.63) 0 1.32px, rgba(255,255,255,0) 2.52px); -webkit-mask-image: radial-gradient(150% 135% at 90% 0%, #000 0%, rgba(0,0,0,0.85) 38%, rgba(0,0,0,0.35) 66%, transparent 92%); mask-image: radial-gradient(150% 135% at 90% 0%, #000 0%, rgba(0,0,0,0.85) 38%, rgba(0,0,0,0.35) 66%, transparent 92%); }
.bg__stars--bright { opacity: var(--stars); background-image: radial-gradient(circle at 98.97% 50.26%, rgba(255,255,255,0.98) 0 2.33px, rgba(255,255,255,0) 3.53px), radial-gradient(circle at 87.08% 0.48%, rgba(255,255,255,0.96) 0 1.84px, rgba(255,255,255,0) 3.04px), radial-gradient(circle at 54.46% 1.14%, rgba(255,255,255,0.91) 0 1.82px, rgba(255,255,255,0) 3.02px), radial-gradient(circle at 84.19% 86.58%, rgba(255,255,255,0.82) 0 1.78px, rgba(255,255,255,0) 2.98px), radial-gradient(circle at 25.50% 98.73%, rgba(255,255,255,0.87) 0 2.45px, rgba(255,255,255,0) 3.65px), radial-gradient(circle at 35.89% 24.10%, rgba(255,255,255,0.80) 0 1.77px, rgba(255,255,255,0) 2.97px), radial-gradient(circle at 27.22% 0.07%, rgba(255,255,255,0.80) 0 1.76px, rgba(255,255,255,0) 2.96px), radial-gradient(circle at 91.63% 5.67%, rgba(255,255,255,0.82) 0 1.81px, rgba(255,255,255,0) 3.01px), radial-gradient(circle at 70.26% 48.27%, rgba(255,255,255,0.96) 0 2.30px, rgba(255,255,255,0) 3.50px), radial-gradient(circle at 80.93% 2.57%, rgba(255,255,255,0.94) 0 2.39px, rgba(255,255,255,0) 3.59px), radial-gradient(circle at 59.33% 51.11%, rgba(255,255,255,0.86) 0 2.29px, rgba(255,255,255,0) 3.49px), radial-gradient(circle at 95.87% 70.56%, rgba(255,255,255,0.94) 0 2.03px, rgba(255,255,255,0) 3.23px), radial-gradient(circle at 32.18% 43.98%, rgba(255,255,255,0.89) 0 2.16px, rgba(255,255,255,0) 3.36px), radial-gradient(circle at 76.57% 5.94%, rgba(255,255,255,0.89) 0 2.46px, rgba(255,255,255,0) 3.66px), radial-gradient(circle at 95.98% 2.06%, rgba(255,255,255,0.98) 0 1.70px, rgba(255,255,255,0) 2.90px), radial-gradient(circle at 74.49% 71.39%, rgba(255,255,255,0.93) 0 2.13px, rgba(255,255,255,0) 3.33px), radial-gradient(circle at 18.87% 96.98%, rgba(255,255,255,0.86) 0 1.67px, rgba(255,255,255,0) 2.87px), radial-gradient(circle at 85.20% 46.67%, rgba(255,255,255,0.92) 0 1.87px, rgba(255,255,255,0) 3.07px), radial-gradient(circle at 61.15% 2.38%, rgba(255,255,255,0.82) 0 1.96px, rgba(255,255,255,0) 3.16px), radial-gradient(circle at 98.89% 79.04%, rgba(255,255,255,0.84) 0 2.33px, rgba(255,255,255,0) 3.53px), radial-gradient(circle at 52.58% 0.83%, rgba(255,255,255,0.87) 0 2.44px, rgba(255,255,255,0) 3.64px), radial-gradient(circle at 53.96% 0.15%, rgba(255,255,255,0.87) 0 2.00px, rgba(255,255,255,0) 3.20px), radial-gradient(circle at 44.14% 21.65%, rgba(255,255,255,0.88) 0 2.06px, rgba(255,255,255,0) 3.26px), radial-gradient(circle at 99.22% 4.13%, rgba(255,255,255,0.85) 0 2.37px, rgba(255,255,255,0) 3.57px), radial-gradient(circle at 95.00% 97.79%, rgba(255,255,255,0.91) 0 1.90px, rgba(255,255,255,0) 3.10px), radial-gradient(circle at 94.13% 63.07%, rgba(255,255,255,0.83) 0 2.02px, rgba(255,255,255,0) 3.22px), radial-gradient(circle at 99.90% 1.05%, rgba(255,255,255,0.91) 0 2.29px, rgba(255,255,255,0) 3.49px), radial-gradient(circle at 95.91% 55.23%, rgba(255,255,255,0.89) 0 2.17px, rgba(255,255,255,0) 3.37px), radial-gradient(circle at 45.85% 38.26%, rgba(255,255,255,0.95) 0 2.31px, rgba(255,255,255,0) 3.51px), radial-gradient(circle at 97.37% 70.85%, rgba(255,255,255,1.00) 0 2.26px, rgba(255,255,255,0) 3.46px), radial-gradient(circle at 16.64% 37.61%, rgba(255,255,255,0.91) 0 1.92px, rgba(255,255,255,0) 3.12px), radial-gradient(circle at 98.12% 19.67%, rgba(255,255,255,0.86) 0 2.48px, rgba(255,255,255,0) 3.68px), radial-gradient(circle at 80.02% 8.81%, rgba(255,255,255,0.84) 0 2.50px, rgba(255,255,255,0) 3.70px), radial-gradient(circle at 93.44% 12.46%, rgba(255,255,255,0.96) 0 1.86px, rgba(255,255,255,0) 3.06px); animation: gaTwinkle 7.5s ease-in-out infinite; animation-play-state: var(--motion); -webkit-mask-image: radial-gradient(115% 100% at 94% 0%, #000 0%, rgba(0,0,0,0.7) 42%, transparent 84%); mask-image: radial-gradient(115% 100% at 94% 0%, #000 0%, rgba(0,0,0,0.7) 42%, transparent 84%); animation: twinkle 7.5s ease-in-out infinite; animation-play-state: var(--motion); }


/* -----------------------------------------------------------------------------
   06  PAGE SHELL
   .shell is the centred column every page sits in: full height, capped width,
   header at the top, footer at the bottom, content filling the space between.
   -------------------------------------------------------------------------- */
.shell {
  position: relative; z-index: 1;          /* sits above .bg */
  min-height: 100svh;
  width: 100%; max-width: 1440px; margin: 0 auto;
  display: flex; flex-direction: column;
  gap: clamp(28px, 7vh, 88px);
  padding: clamp(20px, 3.4vw, 54px);
}

/* Default content area: single column, aligned to the top. */
.main { flex: 1 1 auto; outline: none; display: flex; flex-direction: column; gap: clamp(22px, 3vw, 34px); }

/* Home only: title and card side by side on wide screens, vertically centred. */
.main--split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(26px, 5vw, 88px);
  align-items: center; align-content: center;
}


/* -----------------------------------------------------------------------------
   07  HEADER, BAR AND MENU
   The bar sticks 12px below the top of the viewport. The menu is a native
   <details> element, so it opens and closes without JavaScript; site.js only
   adds the niceties (close on Escape, close on click outside).
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 12px; z-index: 8;
  display: flex; flex-direction: column; align-items: stretch;
  font-size: 13px; letter-spacing: 0.13em; text-transform: uppercase;
  animation: fade-up 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both;
}

.bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 20px;
  padding: 8px 12px 8px clamp(16px, 1.6vw, 24px);
  border: 1px solid var(--cardline);
  border-radius: 30px; corner-shape: squircle;
  background: var(--bar);
  box-shadow: var(--shadow-bar);
}
.bar__brand {
  display: flex; align-items: center; min-height: 44px;
  border: 0; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink);
}
.bar__brand:hover { color: var(--ink); }
.bar__tools { display: flex; align-items: center; gap: 18px; }

/* "In development" status pill with the pulsing dot. */
.status { display: flex; align-items: center; gap: 10px; }
.status__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #4D8BFF; box-shadow: 0 0 14px rgba(77, 139, 255, 0.9);
  animation: pulse 2.8s ease-in-out infinite;
  animation-play-state: var(--motion);
}

/* Round 44px control, used by the theme toggle. */
.icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--cardline); border-radius: 999px;
  background: var(--card); color: var(--ink); cursor: pointer;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.icon-btn:hover { background: var(--hover); border-color: var(--hair); }

/* Sun shows on the dark theme (press it for light); moon shows on the light one. */
.icon-moon { display: none; }
:root[data-theme="light"] .icon-sun { display: none; }
:root[data-theme="light"] .icon-moon { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .icon-sun { display: none; }
  :root:not([data-theme="dark"]) .icon-moon { display: block; }
}

/* Menu: <summary> is the hamburger, the panel is the <nav> inside <details>. */
.menu { position: relative; }
.menu__btn {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 0 0 0 13px;
  cursor: pointer; list-style: none;
}
.menu__btn::-webkit-details-marker { display: none; }   /* Safari's default arrow */
.menu__btn span { display: block; width: 20px; height: 1.5px; background: var(--ink); }

/* The panel floats over the page, so opening it never pushes content down. */
.nav {
  position: absolute; top: calc(100% + 14px); right: -12px; z-index: 12;
  display: flex; flex-direction: column;
  width: max-content; min-width: 236px; max-width: 78vw;
  padding: 8px;
  border: 1px solid var(--cardline);
  border-radius: 24px; corner-shape: squircle;
  background: var(--bar);
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.42);
  transform-origin: top right;
  will-change: transform, opacity;
  animation: drop-in 0.38s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.nav__link {
  display: flex; align-items: center; min-height: 46px;
  padding: 10px 14px;
  border: 0; border-radius: 11px;
  color: var(--ink);
  font-size: 13px; line-height: 1.4; letter-spacing: 0.13em; text-transform: uppercase;
  animation: nav-item 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.nav__link:hover { background: var(--hover); color: var(--ink); }
/* Each link arrives a beat after the one above it. */
.nav__link:nth-child(1) { animation-delay: 0.06s; }
.nav__link:nth-child(2) { animation-delay: 0.10s; }
.nav__link:nth-child(3) { animation-delay: 0.14s; }
.nav__link:nth-child(4) { animation-delay: 0.18s; }
.nav__link:nth-child(5) { animation-delay: 0.22s; }
.nav__link:nth-child(6) { animation-delay: 0.26s; }
/* The page you are currently on. */
.nav__link[aria-current="page"] { background: var(--hover); }


/* -----------------------------------------------------------------------------
   08  BUTTONS  (pill shaped; used for links and actions alike)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 46px; padding: 0 20px;
  border: 1px solid var(--cardline); border-radius: 999px;
  background: var(--card); color: var(--ink); cursor: pointer;
  font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.btn:hover { background: var(--hover); border-color: var(--hair); color: var(--ink); }
.btn--ghost { background: none; min-height: 44px; padding: 0 18px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 10px; }


/* -----------------------------------------------------------------------------
   09  CARDS
   .card is the base frosted panel. Everything below is a variation on it.
   -------------------------------------------------------------------------- */
.card {
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(22px, 2.8vw, 36px);
  border: 1px solid var(--cardline); border-radius: 20px;
  background: var(--card);
  box-shadow: var(--shadow-card);
}
.card--measure { max-width: 30em; }

/* Small uppercase label at the top of a card. */
.card__label { font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }

/* Opening line, set in the display face. */
.card__lead {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(19px, 1.7vw, 25px); line-height: 1.5;
  color: var(--ink); text-wrap: pretty;
}

/* Supporting copy. */
.card__body { font-size: clamp(16px, 1.2vw, 18px); line-height: 1.65; color: var(--muted); text-wrap: pretty; }


/* -----------------------------------------------------------------------------
   10  HOME PAGE
   -------------------------------------------------------------------------- */
.hero-name {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(56px, 13.5vw, 164px); line-height: 0.96; letter-spacing: -0.045em;
  padding: 0.04em 0.1em 0.1em 0;
  text-align: center;
  text-shadow: 0 3px 40px rgba(0, 0, 0, 0.5);
}
.hero-name span { display: block; animation: rise 1.1s cubic-bezier(0.16, 1, 0.3, 1) both; }
.hero-name span:nth-child(1) { animation-delay: 0.15s; }
.hero-name span:nth-child(2) { animation-delay: 0.38s; }

/* From tablet up the name left-aligns and the surname steps in. */
@media (min-width: 700px) {
  .hero-name { text-align: left; }
  .hero-name span:nth-child(2) { margin-left: 0.16em; }
}

.home-intro { display: flex; flex-direction: column; gap: 16px; max-width: 30em; }
.home-intro .card { animation: fade-up 1s cubic-bezier(0.22, 1, 0.36, 1) 0.7s both; }
.home-intro .btn-row { animation: fade-up 1s cubic-bezier(0.22, 1, 0.36, 1) 0.88s both; }


/* -----------------------------------------------------------------------------
   11  PAGE TITLES  (every page except home)
   -------------------------------------------------------------------------- */
.page-title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(54px, 13vw, 152px); line-height: 1.02; letter-spacing: -0.04em;
  padding: 0.04em 0.1em 0.1em 0;
  text-shadow: 0 3px 40px rgba(0, 0, 0, 0.5);
  animation: rise 1s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
}
/* Long titles need a lower ceiling so they do not swamp the page. */
.page-title--long { font-size: clamp(40px, 8vw, 96px); line-height: 1.04; }

/* Content sitting directly under a page title. */
.page-body { animation: fade-up 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.25s both; }


/* -----------------------------------------------------------------------------
   12  PROJECTS GRID
   -------------------------------------------------------------------------- */
.projects { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: 22px; align-items: start; }

.project-card {
  display: flex; flex-direction: column;
  border: 1px solid var(--cardline); border-radius: 24px; corner-shape: squircle;
  background: var(--card); box-shadow: var(--shadow-card);
  overflow: hidden; text-align: left;
  transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.34s cubic-bezier(0.22, 1, 0.36, 1),
              border-color 0.34s ease;
}
/* Lift on hover. Also fires on keyboard focus, so it is not mouse-only. */
.project-card:hover,
.project-card:focus-visible {
  transform: translateY(-6px);
  border-color: var(--hair);
  box-shadow: 0 38px 92px rgba(0, 0, 0, 0.5);
  color: var(--ink);
}
.project-card__media {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 9; object-fit: cover; object-position: 50% 12%;
  border-bottom: 1px solid var(--cardline);
}
.project-card__body { display: flex; flex-direction: column; gap: 12px; padding: clamp(22px, 2.8vw, 32px); }
.project-card__meta {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
}
.project-card__title {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(19px, 1.7vw, 25px); line-height: 1.4; letter-spacing: -0.01em;
  text-wrap: pretty;
}
.project-card__sub { font-size: 14px; line-height: 1.5; color: var(--muted); }


/* -----------------------------------------------------------------------------
   13  PHOTOGRAPHY GALLERY
   Mobile first: ONE column, so no card ever has to share a narrow screen.
   Extra columns appear only when there is room for them.
   -------------------------------------------------------------------------- */
.gallery { display: grid; grid-template-columns: 1fr; gap: 18px; align-items: start; }

@media (min-width: 640px) { .gallery { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); } }

.gallery__item {
  display: flex; flex-direction: column;
  border: 1px solid var(--cardline); border-radius: 24px; corner-shape: squircle;
  background: var(--card); box-shadow: var(--shadow-card);
  overflow: hidden;
  /* Skip layout and paint work for cards scrolled out of view. */
  content-visibility: auto; contain-intrinsic-size: auto 420px;
}
/* Double-width cards. The span applies only once two columns exist, so on a
   phone this rule does nothing and the card simply fills the single column. */
@media (min-width: 900px) { .gallery__item--wide { grid-column: span 2; } }

.gallery__item img { display: block; width: 100%; height: auto; border-bottom: 1px solid var(--cardline); }

/* Photo shown whole rather than cropped (used where the framing matters). */
.gallery__frame { position: relative; width: 100%; aspect-ratio: 4 / 3; border-bottom: 1px solid var(--cardline); background: rgba(0, 0, 0, 0.18); }
.gallery__frame img { width: 100%; height: 100%; object-fit: contain; border-bottom: 0; }

/* Group of images stacked inside one card, separated by hairlines. */
.gallery__stack { display: flex; flex-direction: column; gap: 1px; background: var(--cardline); border-bottom: 1px solid var(--cardline); }
.gallery__stack img { border-bottom: 0; }
.gallery__pair { display: grid; grid-template-columns: 1fr; gap: 1px; }
@media (min-width: 480px) {
  .gallery__pair { grid-template-columns: 1fr 1fr; }
  .gallery__pair img { aspect-ratio: 3 / 2; object-fit: cover; }
}

.gallery__body { display: flex; flex-direction: column; gap: 8px; padding: 18px 20px 20px; }
.gallery__label { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.gallery__caption { font-size: 16px; line-height: 1.55; color: var(--ink); text-wrap: pretty; }
.gallery__text { display: flex; flex-direction: column; gap: 13px; padding: 20px 20px 24px; }
.gallery__lead { font-family: var(--display); font-weight: 400; font-size: 19px; line-height: 1.45; text-wrap: pretty; }
.gallery__para { font-size: 15.5px; line-height: 1.65; text-wrap: pretty; }


/* -----------------------------------------------------------------------------
   14  PROJECT POST  (long-form article with a sidebar)
   -------------------------------------------------------------------------- */
.post-layout { display: flex; flex-wrap: wrap; align-items: flex-start; gap: clamp(20px, 2.4vw, 34px); animation: fade-up 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both; }

.post {
  flex: 1 1 400px;
  display: flex; flex-direction: column; gap: 26px;
  padding: clamp(24px, 3vw, 44px);
  border: 1px solid var(--cardline); border-radius: 20px;
  background: var(--card); box-shadow: var(--shadow-card);
}
.post__header { display: flex; flex-direction: column; gap: 12px; }
.post__eyebrow { font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.post__title { font-family: var(--display); font-weight: 300; font-size: clamp(32px, 4.4vw, 52px); line-height: 1.08; letter-spacing: -0.035em; text-wrap: pretty; }
.post__sub { font-family: var(--display); font-size: clamp(17px, 1.5vw, 21px); line-height: 1.45; color: var(--muted); }
.post__lead { max-width: 34em; font-size: clamp(18px, 1.35vw, 21px); line-height: 1.6; text-wrap: pretty; }
.post__figure { display: flex; flex-direction: column; gap: 10px; max-width: 34em; }
.post__figure img { display: block; width: 100%; height: auto; border: 1px solid var(--cardline); border-radius: 14px; box-shadow: 0 20px 54px rgba(0, 0, 0, 0.36); }
.post__figure figcaption { font-size: 13px; line-height: 1.5; color: var(--muted); }
.post__intro { display: flex; flex-direction: column; gap: 14px; max-width: 34em; }

/* Every section is separated by a rule above it. */
.post__section { display: flex; flex-direction: column; gap: 12px; max-width: 34em; padding-top: 22px; border-top: 1px solid var(--cardline); }
.post__section h2 { font-size: 12px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.post p { font-size: clamp(16px, 1.15vw, 17.5px); line-height: 1.72; text-wrap: pretty; }

/* Sidebar. Sticks below the header on wide screens; flows inline on narrow ones. */
.post__aside {
  flex: 0 1 290px;
  display: flex; flex-direction: column; gap: 20px;
  padding: clamp(22px, 2.4vw, 30px);
  border: 1px solid var(--cardline); border-radius: 20px;
  background: var(--card); box-shadow: var(--shadow-card);
}
@media (min-width: 900px) { .post__aside { position: sticky; top: 92px; } }

/* Vertical pipeline diagram inside the sidebar. */
.pipeline { display: flex; flex-direction: column; }
.pipeline__step { display: flex; gap: 14px; }
.pipeline__rail { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.pipeline__dot { width: 11px; height: 11px; border-radius: 50%; }
.pipeline__line { width: 1px; flex: 1; min-height: 30px; background: var(--cardline); }
.pipeline__text { display: flex; flex-direction: column; gap: 3px; padding-bottom: 18px; }
.pipeline__step:last-child .pipeline__text { padding-bottom: 0; }
.pipeline__name { font-size: 15px; letter-spacing: -0.01em; color: var(--ink); }
.pipeline__note { font-size: 13px; line-height: 1.45; color: var(--muted); }
/* Dots walk through the gradient ramp, top to bottom. */
.pipeline__step:nth-child(1) .pipeline__dot { background: var(--g1); box-shadow: 0 0 12px var(--g1); }
.pipeline__step:nth-child(2) .pipeline__dot { background: var(--g2); box-shadow: 0 0 12px var(--g2); }
.pipeline__step:nth-child(3) .pipeline__dot { background: var(--g3); box-shadow: 0 0 12px var(--g3); }
.pipeline__step:nth-child(4) .pipeline__dot { background: var(--g4); box-shadow: 0 0 12px var(--g4); }
.pipeline__step:nth-child(5) .pipeline__dot { background: var(--g5); box-shadow: 0 0 12px var(--g5); }


/* -----------------------------------------------------------------------------
   15  FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 24px;
  padding-top: 14px; border-top: 1px solid var(--hair);
  font-size: 13px; letter-spacing: 0.06em; color: var(--muted);
  animation: fade-up 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.95s both;
}
/* Right-hand group: LinkedIn link, then the build status pill. */
.site-footer__end { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 20px; }
.site-footer .status { font-size: 12px; letter-spacing: 0.13em; text-transform: uppercase; }
.site-footer a { display: inline-flex; align-items: center; gap: 9px; min-height: 44px; border: 0; color: var(--muted); }
.site-footer a:hover { color: var(--ink); }


/* -----------------------------------------------------------------------------
   16  KEYFRAMES
   -------------------------------------------------------------------------- */
@keyframes pulse   { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.8); } }
@keyframes flow    { from { background-position: 0vw 50%; } to { background-position: -320vw 50%; } }
@keyframes breathe { 0% { transform: scale(1) translate3d(0, 0, 0); opacity: 0.3; } 50% { transform: scale(1.14) translate3d(2%, -2%, 0); opacity: 0.4; } 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 0.3; } }
@keyframes twinkle { 0%, 100% { opacity: var(--stars); } 50% { opacity: var(--stars-dim); } }
@keyframes rise    { from { opacity: 0; transform: translate3d(0, 0.34em, 0); filter: blur(10px); } to { opacity: 1; transform: translate3d(0, 0, 0); filter: blur(0); } }
@keyframes fade-up { from { opacity: 0; transform: translate3d(0, 14px, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }
@keyframes drop-in { from { opacity: 0; transform: translate3d(0, -14px, 0) scale(0.97); } to { opacity: 1; transform: translate3d(0, 0, 0) scale(1); } }
@keyframes nav-item { from { opacity: 0; transform: translate3d(0, -7px, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }


/* -----------------------------------------------------------------------------
   17  REDUCED MOTION
   Honour the operating-system setting: keep every end state, skip the travel.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
}
