/* ==========================================================================
   DESIGN SYSTEM — NEOBRUTALISM
   Flat saturated colour, hard 2px black borders, offset shadows with no blur,
   and a press interaction where the element slides into its own shadow.
   Every foreground/background pair below passes WCAG AA.
   ========================================================================== */

:root {
  /* --- Surfaces --- */
  --surface: #ffffff;
  --surface-alt: #f3f5fb;

  /* --- Ink --- */
  --ink: #000000;
  --ink-muted: #4a4a4a; /* >= 6.9:1 on every theme background */

  /* --- Fixed: the "available" status dot reads green in every theme --- */
  --green: #a3e636; /* black on it 13.9:1 */

  /* --- Structure --- */
  --border: #000000;
  --border-w: 2px;
  --border-w-thick: 3px;
  --radius: 5px;

  /* --- Offset shadows (never blurred) --- */
  --shadow-sm: 2px 2px 0 0 var(--border);
  --shadow: 4px 4px 0 0 var(--border);
  --shadow-lg: 8px 8px 0 0 var(--border);

  /* --- Fonts --- */
  --font-default: 'Public Sans', system-ui, -apple-system, sans-serif;
  --font-heading: 'Public Sans', system-ui, -apple-system, sans-serif;

  /* --- Motion: short and snappy, nothing eased over long durations --- */
  --transition-smooth: all 0.12s ease-out;
}

/* ==========================================================================
   COLOUR THEMES
   Cycled by the Spider-Sense button. Structure (borders, shadows, radii,
   type) never changes; only the four colour slots below do. Black text sits
   on --main / --accent-2 / --accent-3 in every theme, so contrast is safe by
   construction. Ratios noted per value.
   ========================================================================== */

:root,
[data-theme='red'] {
  --background: #dfe5f2; /* black on it 16.6:1 */
  --main: #ff5470; /* black on it  6.8:1 */
  --main-overlay: rgba(255, 84, 112, 0.88);
  --accent-2: #ffdc58; /* black on it 15.6:1 */
  --accent-3: #88aaee; /* black on it  9.0:1 */
  --ink-accent: #b31239; /* 6.9:1 on surface, 5.4:1 on background */
}

[data-theme='blue'] {
  --background: #fdf0e4; /* black on it 18.8:1 */
  --main: #88aaee; /* black on it  9.0:1 */
  --main-overlay: rgba(136, 170, 238, 0.9);
  --accent-2: #a3e636; /* black on it 13.9:1 */
  --accent-3: #ffdc58; /* black on it 15.6:1 */
  --ink-accent: #1b4fa8; /* 7.7:1 on surface, 6.9:1 on background */
}

[data-theme='yellow'] {
  --background: #e6e2f5; /* black on it 16.6:1 */
  --main: #ffdc58; /* black on it 15.6:1 */
  --main-overlay: rgba(255, 220, 88, 0.9);
  --accent-2: #88aaee; /* black on it  9.0:1 */
  --accent-3: #ff5470; /* black on it  6.8:1 */
  --ink-accent: #8a4b00; /* 6.8:1 on surface, 5.4:1 on background */
}


/* ==========================================================================
   RESET & BASE
   ========================================================================== */

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

/* A type selector outranks the universal reset above, so this is the paragraph
   rhythm the layout is actually built on. It used to come from Bootstrap's
   Reboot; components that want something else still override it. */
p {
  margin-bottom: 1rem;
}

/* User agents give form controls their own font stack and a line-height of
   `normal`. Inherit instead, otherwise a <button> styled as a button comes out
   shorter than an <a> styled the same way. */
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}
button {
  text-transform: none;
}

body {
  font-family: var(--font-default);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.6;
  color: var(--ink);
  background-color: var(--background);
  background-image: radial-gradient(rgba(0, 0, 0, 0.09) 1px, transparent 1px);
  background-size: 22px 22px;
  overflow-x: hidden;
  transition: background-color 0.25s ease-out;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-heading);
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

a {
  color: var(--ink);
  text-decoration: none;
  font-weight: 700;
  transition: var(--transition-smooth);
}
a:hover {
  color: var(--ink-accent);
}

::selection {
  background: var(--main);
  color: var(--ink);
}

:focus-visible {
  outline: var(--border-w-thick) solid var(--border);
  outline-offset: 2px;
}

/* Hide scrollbar while keeping page scrollable */
html {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
::-webkit-scrollbar {
  display: none;
}

/* Particle field - disabled along with the canvas effect in script.js.
#spidey-web-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
  pointer-events: none;
}
*/

/* ==========================================================================
   LAYOUT PRIMITIVES
   Replaces Bootstrap's grid and the handful of utilities this page used. Only
   the classes actually present in the markup are defined here. Breakpoints and
   the spacing scale match Bootstrap 5 so the existing markup and the component
   media queries below keep behaving identically.

   Utilities carry !important exactly where Bootstrap put it - .d-none has to
   beat .mobile-nav-toggle { display: block }, for instance - while .fixed-top
   deliberately does not, so .header { z-index: 997 } still wins.

   Breakpoints: sm 576  md 768  lg 992  xl 1200  xxl 1400
   Spacing:      0 = 0   2 = .5rem   3 = 1rem   4 = 1.5rem
   ========================================================================== */

.container,
.container-fluid {
  width: 100%;
  margin-inline: auto;
  padding-inline: 0.75rem;
}

@media (min-width: 576px) {
  .container {
    max-width: 540px;
  }
}
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}
@media (min-width: 992px) {
  .container {
    max-width: 960px;
  }
}
@media (min-width: 1200px) {
  .container {
    max-width: 1140px;
  }
}
@media (min-width: 1400px) {
  .container {
    max-width: 1320px;
  }
}

.row {
  --grid-gutter-x: 1.5rem;
  --grid-gutter-y: 0;
  display: flex;
  flex-wrap: wrap;
  margin-top: calc(-1 * var(--grid-gutter-y));
  margin-right: calc(-0.5 * var(--grid-gutter-x));
  margin-left: calc(-0.5 * var(--grid-gutter-x));
}
.row > * {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-right: calc(var(--grid-gutter-x) * 0.5);
  padding-left: calc(var(--grid-gutter-x) * 0.5);
  margin-top: var(--grid-gutter-y);
}

.gy-4 {
  --grid-gutter-y: 1.5rem;
}

/* Columns: full width until the breakpoint, then a fraction of twelve */
@media (min-width: 768px) {
  .col-md-5,
  .col-md-6,
  .col-md-7 {
    flex: 0 0 auto;
  }
  .col-md-5 {
    width: 41.66666667%;
  }
  .col-md-6 {
    width: 50%;
  }
  .col-md-7 {
    width: 58.33333333%;
  }
}

@media (min-width: 992px) {
  .col-lg-4,
  .col-lg-5,
  .col-lg-8,
  .col-lg-10 {
    flex: 0 0 auto;
  }
  .col-lg-4 {
    width: 33.33333333%;
  }
  .col-lg-5 {
    width: 41.66666667%;
  }
  .col-lg-8 {
    width: 66.66666667%;
  }
  .col-lg-10 {
    width: 83.33333333%;
  }
}

@media (min-width: 1200px) {
  .col-xl-3 {
    flex: 0 0 auto;
    width: 25%;
  }
}

/* --- Display & flex --- */
.d-flex {
  display: flex !important;
}
.d-none {
  display: none !important;
}
.flex-column {
  flex-direction: column !important;
}
.flex-wrap {
  flex-wrap: wrap !important;
}
.align-items-center {
  align-items: center !important;
}
.justify-content-center {
  justify-content: center !important;
}
.justify-content-between {
  justify-content: space-between !important;
}
.gap-2 {
  gap: 0.5rem !important;
}
.gap-3 {
  gap: 1rem !important;
}

/* --- Spacing --- */
.p-0 {
  padding: 0 !important;
}
.mt-2 {
  margin-top: 0.5rem !important;
}
.mt-3 {
  margin-top: 1rem !important;
}
.mt-4 {
  margin-top: 1.5rem !important;
}
.mb-2 {
  margin-bottom: 0.5rem !important;
}
.me-auto {
  margin-right: auto !important;
}

/* --- Sizing, text, position --- */
.h-100 {
  height: 100% !important;
}
.text-center {
  text-align: center !important;
}
.position-relative {
  position: relative !important;
}
.img-fluid {
  max-width: 100%;
  height: auto;
}
.fixed-top {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 1030;
}

/* --- Responsive variants --- */
@media (min-width: 992px) {
  .justify-content-lg-start {
    justify-content: flex-start !important;
  }
  .text-lg-start {
    text-align: left !important;
  }
  .me-lg-0 {
    margin-right: 0 !important;
  }
}

/* icons:start */
/* Generated by tools/build-icons.js - do not edit by hand.
   Bootstrap Icons v1.11.3, 29 glyphs, drawn as masks so that
   <i class="bi bi-name"> keeps working with no font request. The glyph takes
   its colour from currentColor and its size from font-size, exactly like the
   font did. */

.bi::before,
[class^='bi-']::before,
[class*=' bi-']::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
  line-height: 1;
  vertical-align: -0.125em;
  background-color: currentColor;
  -webkit-mask: var(--bi) center / contain no-repeat;
  mask: var(--bi) center / contain no-repeat;
}

.bi-arrow-up-short {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M8 12a.5.5 0 0 0 .5-.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 .5.5'/%3E %3C/svg%3E");
}
.bi-award-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z'/%3E %3Cpath d='M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z'/%3E %3C/svg%3E");
}
.bi-box-arrow-up-right {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5'/%3E %3Cpath fill-rule='evenodd' d='M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z'/%3E %3C/svg%3E");
}
.bi-briefcase-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M6.5 1A1.5 1.5 0 0 0 5 2.5V3H1.5A1.5 1.5 0 0 0 0 4.5v1.384l7.614 2.03a1.5 1.5 0 0 0 .772 0L16 5.884V4.5A1.5 1.5 0 0 0 14.5 3H11v-.5A1.5 1.5 0 0 0 9.5 1zm0 1h3a.5.5 0 0 1 .5.5V3H6v-.5a.5.5 0 0 1 .5-.5'/%3E %3Cpath d='M0 12.5A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5V6.85L8.129 8.947a.5.5 0 0 1-.258 0L0 6.85z'/%3E %3C/svg%3E");
}
.bi-bug-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M4.978.855a.5.5 0 1 0-.956.29l.41 1.352A5 5 0 0 0 3 6h10a5 5 0 0 0-1.432-3.503l.41-1.352a.5.5 0 1 0-.956-.29l-.291.956A5 5 0 0 0 8 1a5 5 0 0 0-2.731.811l-.29-.956z'/%3E %3Cpath d='M13 6v1H8.5v8.975A5 5 0 0 0 13 11h.5a.5.5 0 0 1 .5.5v.5a.5.5 0 1 0 1 0v-.5a1.5 1.5 0 0 0-1.5-1.5H13V9h1.5a.5.5 0 0 0 0-1H13V7h.5A1.5 1.5 0 0 0 15 5.5V5a.5.5 0 0 0-1 0v.5a.5.5 0 0 1-.5.5zm-5.5 9.975V7H3V6h-.5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 0-1 0v.5A1.5 1.5 0 0 0 2.5 7H3v1H1.5a.5.5 0 0 0 0 1H3v1h-.5A1.5 1.5 0 0 0 1 11.5v.5a.5.5 0 1 0 1 0v-.5a.5.5 0 0 1 .5-.5H3a5 5 0 0 0 4.5 4.975'/%3E %3C/svg%3E");
}
.bi-calendar-event {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z'/%3E %3Cpath d='M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z'/%3E %3C/svg%3E");
}
.bi-circle-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Ccircle cx='8' cy='8' r='8'/%3E %3C/svg%3E");
}
.bi-envelope-at-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M2 2A2 2 0 0 0 .05 3.555L8 8.414l7.95-4.859A2 2 0 0 0 14 2zm-2 9.8V4.698l5.803 3.546zm6.761-2.97-6.57 4.026A2 2 0 0 0 2 14h6.256A4.5 4.5 0 0 1 8 12.5a4.49 4.49 0 0 1 1.606-3.446l-.367-.225L8 9.586zM16 9.671V4.697l-5.803 3.546.338.208A4.5 4.5 0 0 1 12.5 8c1.414 0 2.675.652 3.5 1.671'/%3E %3Cpath d='M15.834 12.244c0 1.168-.577 2.025-1.587 2.025-.503 0-1.002-.228-1.12-.648h-.043c-.118.416-.543.643-1.015.643-.77 0-1.259-.542-1.259-1.434v-.529c0-.844.481-1.4 1.26-1.4.585 0 .87.333.953.63h.03v-.568h.905v2.19c0 .272.18.42.411.42.315 0 .639-.415.639-1.39v-.118c0-1.277-.95-2.326-2.484-2.326h-.04c-1.582 0-2.64 1.067-2.64 2.724v.157c0 1.867 1.237 2.654 2.57 2.654h.045c.507 0 .935-.07 1.18-.18v.731c-.219.1-.643.175-1.237.175h-.044C10.438 16 9 14.82 9 12.646v-.214C9 10.36 10.421 9 12.485 9h.035c2.12 0 3.314 1.43 3.314 3.034zm-4.04.21v.227c0 .586.227.8.581.8.31 0 .564-.17.564-.743v-.367c0-.516-.275-.708-.572-.708-.346 0-.573.245-.573.791'/%3E %3C/svg%3E");
}
.bi-facebook {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951'/%3E %3C/svg%3E");
}
.bi-file-earmark-arrow-down-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0M9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1m-1 4v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 11.293V7.5a.5.5 0 0 1 1 0'/%3E %3C/svg%3E");
}
.bi-geo-alt-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6'/%3E %3C/svg%3E");
}
.bi-github {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8'/%3E %3C/svg%3E");
}
.bi-grid-3x3-gap-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M1 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1zM1 7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1zM1 12a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1zm5 0a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1z'/%3E %3C/svg%3E");
}
.bi-heptagon-half {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M7.779.052a.5.5 0 0 1 .442 0l6.015 2.97a.5.5 0 0 1 .267.34l1.485 6.676a.5.5 0 0 1-.093.415l-4.162 5.354a.5.5 0 0 1-.395.193H4.662a.5.5 0 0 1-.395-.193L.105 10.453a.5.5 0 0 1-.093-.415l1.485-6.676a.5.5 0 0 1 .267-.34zM8 15h3.093l3.868-4.975-1.383-6.212L8 1.058z'/%3E %3C/svg%3E");
}
.bi-instagram {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.9 3.9 0 0 0-1.417.923A3.9 3.9 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.9 3.9 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.9 3.9 0 0 0-.923-1.417A3.9 3.9 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599s.453.546.598.92c.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.5 2.5 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.5 2.5 0 0 1-.92-.598 2.5 2.5 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233s.008-2.388.046-3.231c.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92s.546-.453.92-.598c.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92m-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217m0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334'/%3E %3C/svg%3E");
}
.bi-lightning-charge-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M11.251.068a.5.5 0 0 1 .227.58L9.677 6.5H13a.5.5 0 0 1 .364.843l-8 8.5a.5.5 0 0 1-.842-.49L6.323 9.5H3a.5.5 0 0 1-.364-.843l8-8.5a.5.5 0 0 1 .615-.09z'/%3E %3C/svg%3E");
}
.bi-lightning-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641z'/%3E %3C/svg%3E");
}
.bi-linkedin {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854zm4.943 12.248V6.169H2.542v7.225zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248S2.4 3.226 2.4 3.934c0 .694.521 1.248 1.327 1.248zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016l.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225z'/%3E %3C/svg%3E");
}
.bi-list {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5'/%3E %3C/svg%3E");
}
.bi-mortarboard-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M8.211 2.047a.5.5 0 0 0-.422 0l-7.5 3.5a.5.5 0 0 0 .025.917l7.5 3a.5.5 0 0 0 .372 0L14 7.14V13a1 1 0 0 0-1 1v2h3v-2a1 1 0 0 0-1-1V6.739l.686-.275a.5.5 0 0 0 .025-.917z'/%3E %3Cpath d='M4.176 9.032a.5.5 0 0 0-.656.327l-.5 1.7a.5.5 0 0 0 .294.605l4.5 1.8a.5.5 0 0 0 .372 0l4.5-1.8a.5.5 0 0 0 .294-.605l-.5-1.7a.5.5 0 0 0-.656-.327L8 10.466z'/%3E %3C/svg%3E");
}
.bi-person-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6'/%3E %3C/svg%3E");
}
.bi-play-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393'/%3E %3C/svg%3E");
}
.bi-shield-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56'/%3E %3C/svg%3E");
}
.bi-shield-fill-check {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M8 0c-.69 0-1.843.265-2.928.56-1.11.3-2.229.655-2.887.87a1.54 1.54 0 0 0-1.044 1.262c-.596 4.477.787 7.795 2.465 9.99a11.8 11.8 0 0 0 2.517 2.453c.386.273.744.482 1.048.625.28.132.581.24.829.24s.548-.108.829-.24a7 7 0 0 0 1.048-.625 11.8 11.8 0 0 0 2.517-2.453c1.678-2.195 3.061-5.513 2.465-9.99a1.54 1.54 0 0 0-1.044-1.263 63 63 0 0 0-2.887-.87C9.843.266 8.69 0 8 0m2.146 5.146a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 7.793z'/%3E %3C/svg%3E");
}
.bi-shield-shaded {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M8 14.933a1 1 0 0 0 .1-.025q.114-.034.294-.118c.24-.113.547-.29.893-.533a10.7 10.7 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56'/%3E %3C/svg%3E");
}
.bi-telephone-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.68.68 0 0 0 .178.643l2.457 2.457a.68.68 0 0 0 .644.178l2.189-.547a1.75 1.75 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065-2.877.702a18.6 18.6 0 0 1-7.01-4.42 18.6 18.6 0 0 1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877z'/%3E %3C/svg%3E");
}
.bi-trophy-fill {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M2.5.5A.5.5 0 0 1 3 0h10a.5.5 0 0 1 .5.5q0 .807-.034 1.536a3 3 0 1 1-1.133 5.89c-.79 1.865-1.878 2.777-2.833 3.011v2.173l1.425.356c.194.048.377.135.537.255L13.3 15.1a.5.5 0 0 1-.3.9H3a.5.5 0 0 1-.3-.9l1.838-1.379c.16-.12.343-.207.537-.255L6.5 13.11v-2.173c-.955-.234-2.043-1.146-2.833-3.012a3 3 0 1 1-1.132-5.89A33 33 0 0 1 2.5.5m.099 2.54a2 2 0 0 0 .72 3.935c-.333-1.05-.588-2.346-.72-3.935m10.083 3.935a2 2 0 0 0 .72-3.935c-.133 1.59-.388 2.885-.72 3.935'/%3E %3C/svg%3E");
}
.bi-x {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E %3C/svg%3E");
}
.bi-zoom-in {
  --bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 16 16'%3E %3Cpath fill-rule='evenodd' d='M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11M13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0'/%3E %3Cpath d='M10.344 11.742q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1 6.5 6.5 0 0 1-1.398 1.4z'/%3E %3Cpath fill-rule='evenodd' d='M6.5 3a.5.5 0 0 1 .5.5V6h2.5a.5.5 0 0 1 0 1H7v2.5a.5.5 0 0 1-1 0V7H3.5a.5.5 0 0 1 0-1H6V3.5a.5.5 0 0 1 .5-.5'/%3E %3C/svg%3E");
}
/* icons:end */

/* --------------------------------------------------------------------------
   Shared primitives
   -------------------------------------------------------------------------- */

/* Card: the block everything else is built from */
.glass-card {
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px;
  position: relative;
  transition: var(--transition-smooth);
}
.glass-card:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 0 var(--border);
}

/* Press behaviour: the control slides into its own shadow */
.btn-main-action:active,
.btn-secondary-action:active,
.filter-btn:active,
.scroll-top:active,
.gallery-links a:active {
  transform: translate(4px, 4px);
  box-shadow: 0 0 0 0 var(--border);
}

/* ==========================================================================
   RIGHT-CLICK CONTACT MENU
   ========================================================================== */

.context-contact-menu {
  position: fixed;
  z-index: 99999;
  min-width: 232px;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(4px, 4px);
  transition:
    opacity 0.12s ease-out,
    transform 0.12s ease-out,
    visibility 0.12s ease-out;
  overflow: hidden;
}
.context-contact-menu.visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(0, 0);
}

.context-contact-menu-header {
  padding: 10px 14px;
  background: var(--accent-2);
  border-bottom: var(--border-w) solid var(--border);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
}

.context-contact-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  border-bottom: var(--border-w) solid var(--border);
  transition: var(--transition-smooth);
}
.context-contact-menu-item:last-child {
  border-bottom: none;
}
.context-contact-menu-item:hover {
  background: var(--main);
  color: var(--ink);
  text-decoration: none;
}
.context-contact-menu-item i {
  font-size: 16px;
  width: 18px;
  text-align: center;
}
.context-contact-menu-item .text-crimson {
  color: var(--ink-accent);
}
.context-contact-menu-item .text-gold,
.context-contact-menu-item .text-blue,
.context-contact-menu-item .text-web {
  color: var(--ink);
}

/* ==========================================================================
   SECTION HEADER
   ========================================================================== */

.section-title {
  margin-bottom: 48px;
}
.section-title h2 {
  display: inline-block;
  font-size: 40px;
  font-weight: 900;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--main);
  border: var(--border-w-thick) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px 24px;
  margin-bottom: 18px;
}
.section-title p {
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink);
}

/* ==========================================================================
   HEADER & NAVBAR
   ========================================================================== */

.header {
  z-index: 997;
  padding: 16px 0;
  height: 78px;
  background: var(--surface);
  border-bottom: var(--border-w-thick) solid var(--border);
  transition: var(--transition-smooth);
}
.header.header-scrolled {
  height: 68px;
  padding: 12px 0;
  box-shadow: 0 4px 0 0 var(--border);
}

.header .logo h1 {
  font-size: 28px;
  font-weight: 900;
  color: var(--ink);
  margin: 0 0 0 10px;
  display: flex;
  align-items: center;
  letter-spacing: -0.03em;
}
.logo-spidey-icon {
  font-size: 24px;
  color: var(--main);
}
/* -webkit-text-stroke paints glyph outlines only, so a masked icon needs its
   black keyline built from zero-blur drop-shadows. The filter has to sit on the
   element, not on the masked ::before: filter is applied before mask, so a
   shadow declared alongside the mask would be masked away with it. */
.logo-spidey-icon {
  filter:
    drop-shadow(1px 0 0 var(--border)) drop-shadow(-1px 0 0 var(--border))
    drop-shadow(0 1px 0 var(--border)) drop-shadow(0 -1px 0 var(--border));
}
/* Desktop navigation */
.navbar {
  padding: 0;
}
.navbar ul {
  margin: 0;
  padding: 0;
  display: flex;
  list-style: none;
  align-items: center;
  gap: 6px;
}
.navbar a {
  display: flex;
  align-items: center;
  padding: 7px 12px;
  font-family: var(--font-heading);
  text-transform: uppercase;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
  border: var(--border-w) solid transparent;
  border-radius: 4px;
}
.navbar a:hover,
.navbar li:hover > a {
  background: var(--accent-2);
  border-color: var(--border);
  color: var(--ink);
}
.navbar .active {
  background: var(--main);
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
}

.header-social-links a {
  color: var(--ink);
  padding-left: 16px;
  display: inline-block;
  font-size: 18px;
}
.header-social-links a:hover {
  color: var(--ink-accent);
}

/* Mobile navigation */
.mobile-nav-toggle {
  color: var(--ink);
  font-size: 28px;
  cursor: pointer;
  line-height: 0;
  display: none;
}

@media (max-width: 991px) {
  .mobile-nav-toggle {
    display: block;
  }
  .navbar {
    position: fixed;
    top: 0;
    right: -100%;
    width: 100%;
    max-width: 300px;
    bottom: 0;
    transition: right 0.25s ease-out;
    z-index: 9997;
  }
  .navbar ul {
    position: absolute;
    inset: 0;
    padding: 84px 20px 30px;
    margin: 0;
    gap: 10px;
    background: var(--surface);
    border-left: var(--border-w-thick) solid var(--border);
    overflow-y: auto;
    flex-direction: column;
    align-items: stretch;
  }
  .navbar a {
    padding: 12px 16px;
    font-size: 16px;
    width: 100%;
    border-color: var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
  }
  .mobile-nav-active .navbar {
    right: 0;
  }
  /* The overlay is a child of .navbar, which is its own stacking context, so
     this z-index is scoped to that context: it must be negative to sit behind
     the panel (the ul is z-index: auto) rather than on top of it. */
  .mobile-nav-active .navbar:before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: -1;
  }
  /* .navbar is nested inside .header, so the whole drawer is capped by the
     header's z-index. Lift the header while the drawer is open, otherwise
     .scroll-top (999) paints over the overlay. */
  .mobile-nav-active .header {
    z-index: 9998;
  }

  /* Social links relocate into the drawer on mobile (moved by script.js) */
  .nav-social {
    margin-top: auto;
    padding-top: 18px;
    border-top: var(--border-w) solid var(--border);
  }
  .nav-social .header-social-links {
    display: flex;
    justify-content: center;
    gap: 10px;
  }
  .nav-social .header-social-links a {
    width: 46px;
    height: 46px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
    background: var(--surface);
    border: var(--border-w) solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    transition: var(--transition-smooth);
  }
  .nav-social .header-social-links a:hover {
    background: var(--accent-2);
    color: var(--ink);
  }
  .nav-social .header-social-links a:active {
    transform: translate(2px, 2px);
    box-shadow: 0 0 0 0 var(--border);
  }
  .mobile-nav-active .mobile-nav-show {
    display: none;
  }
  .mobile-nav-active .mobile-nav-hide {
    display: block;
    position: fixed;
    right: 20px;
    top: 24px;
    z-index: 9999;
  }
}

/* ==========================================================================
   HERO
   ========================================================================== */

.hero {
  width: 100%;
  min-height: 100vh;
  padding: 120px 0 60px;
  position: relative;
}

.hero .web-intro {
  display: inline-block;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--accent-2);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 6px 12px;
  margin-bottom: 20px;
}

.hero .name-title {
  font-size: 56px;
  font-weight: 900;
  line-height: 1.25;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  margin-bottom: 18px;
}
/* Marker highlight that survives a line break */
.hero .name-title span {
  color: var(--ink);
  background: var(--main);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 2px 10px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.hero .typing-container {
  font-size: 22px;
  font-weight: 800;
  color: var(--ink);
  margin-top: 26px;
  margin-bottom: 18px;
}
.hero .typed-text {
  background: var(--accent-3);
  border: var(--border-w) solid var(--border);
  border-radius: 4px;
  padding: 1px 8px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hero .typed-cursor {
  animation: blink 1s steps(1, end) infinite;
  color: var(--ink);
  font-weight: 800;
}

.hero .intro-desc {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.7;
  color: var(--ink-muted);
  max-width: 540px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn-main-action,
.btn-secondary-action {
  padding: 13px 24px;
  font-family: var(--font-heading);
  font-size: 14px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  white-space: nowrap;
  cursor: pointer;
  transition: var(--transition-smooth);
}
.btn-main-action {
  background: var(--main);
}
.btn-secondary-action {
  background: var(--surface);
}
.btn-main-action:hover,
.btn-secondary-action:hover {
  transform: translate(2px, 2px);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   HERO PORTRAIT
   Cut-out subject standing in a stack of flat discs and breaking past the top
   edge. --px / --py are written by script.js on pointer move; each layer
   consumes them at a different multiplier to separate the planes.
   -------------------------------------------------------------------------- */

.hero .contain-img {
  display: flex;
  justify-content: center;
  align-items: center;
}

.avatar-stage {
  position: relative;
  width: 100%;
  max-width: 360px;
  aspect-ratio: 1 / 1;
  margin: 130px auto 0;
  isolation: isolate;
}

/* Flat colour disc offset down-left behind the white one */
.avatar-halo {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  background: var(--accent-2);
  border: var(--border-w-thick) solid var(--border);
  transform: translate3d(
    calc(-15px + var(--px, 0px) * -0.35),
    calc(15px + var(--py, 0px) * -0.35),
    0
  );
  transition: transform 0.35s ease-out;
}

/* Second flat disc offset up-right */
.avatar-arc {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  background: var(--accent-3);
  border: var(--border-w-thick) solid var(--border);
  transform: translate3d(
    calc(16px + var(--px, 0px) * -0.35),
    calc(-13px + var(--py, 0px) * -0.35),
    0
  );
  transition: transform 0.35s ease-out;
}

/* The disc the subject stands in */
.avatar-disc {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  z-index: 1;
  overflow: hidden;
  background: var(--surface);
  border: var(--border-w-thick) solid var(--border);
  transform: translate3d(
    calc(var(--px, 0px) * -0.18),
    calc(var(--py, 0px) * -0.18),
    0
  );
  transition: transform 0.35s ease-out;
}

/* Dot field inside the disc */
.avatar-disc::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: radial-gradient(rgba(0, 0, 0, 0.16) 1px, transparent 1px);
  background-size: 14px 14px;
}

/* Contact shadow pooling at the subject's base */
.avatar-disc::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 7%;
  width: 58%;
  height: 11%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.18);
  filter: blur(7px);
  z-index: 1;
}

/* The subject - overflows the disc at the top, dissolves at the base */
.avatar-cutout {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 3;
  width: 94%;
  max-width: none;
  height: auto;
  transform: translate3d(calc(-50% + var(--px, 0px)), var(--py, 0px), 0);
  transition: transform 0.3s ease-out;
  filter: drop-shadow(0 12px 14px rgba(0, 0, 0, 0.3));
  /* Union of two masks: everything above the disc's centre line shows in
     full, everything below is clipped to the disc's circle. Geometry is
     derived from the 1086x1448 source at width: 94% of a square stage. */
  -webkit-mask-image:
    linear-gradient(to bottom, #000 0 60.1%, transparent 60.1%),
    radial-gradient(
      ellipse 51.1% 38.3% at 50% 60.1%,
      #000 97%,
      transparent 100%
    );
  mask-image:
    linear-gradient(to bottom, #000 0 60.1%, transparent 60.1%),
    radial-gradient(
      ellipse 51.1% 38.3% at 50% 60.1%,
      #000 97%,
      transparent 100%
    );
}

/* Availability chip anchored to the rim */
.avatar-caption {
  position: absolute;
  z-index: 4;
  left: -8%;
  bottom: 13%;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 13px;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  transform: translate3d(
    calc(var(--px, 0px) * 0.5),
    calc(var(--py, 0px) * 0.5),
    0
  );
  transition: transform 0.32s ease-out;
}
.avatar-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--green);
  border: 2px solid var(--border);
}

@media (max-width: 991px) {
  .hero {
    padding: 100px 0 40px;
    text-align: center;
  }
  .hero .name-title {
    font-size: 40px;
  }
  .avatar-stage {
    max-width: 280px;
    margin-top: 120px;
  }
  .avatar-caption {
    left: -10%;
    bottom: 10%;
  }
}

@media (max-width: 575px) {
  .hero .name-title {
    font-size: 30px;
  }
  .section-title h2 {
    font-size: 26px;
    padding: 8px 16px;
  }
  .avatar-stage {
    max-width: 230px;
    margin-top: 105px;
  }
  .avatar-caption {
    font-size: 10px;
    padding: 6px 11px;
  }
  .btn-main-action,
  .btn-secondary-action {
    padding: 12px 16px;
    font-size: 13px;
  }
  .hero-actions {
    flex-wrap: wrap;
  }
  .hero-actions .btn-main-action,
  .hero-actions .btn-secondary-action {
    flex: 1 1 100%;
  }
  .header .logo h1 {
    font-size: 22px;
  }
  .logo-spidey-icon {
    font-size: 19px;
  }
  .header-social-links a {
    padding-left: 11px;
    font-size: 15px;
  }
}

/* ==========================================================================
   ABOUT
   ========================================================================== */

.about {
  padding: 96px 0;
  position: relative;
  border-top: var(--border-w-thick) solid var(--border);
}

.about-card {
  overflow: hidden;
  z-index: 1;
}

.spidey-suit-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(0, 0, 0, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
  background-size: 24px 24px;
  z-index: -1;
  pointer-events: none;
}

.badge-spidey-large {
  font-size: 76px;
  color: var(--main);
}
.badge-spidey-large {
  filter:
    drop-shadow(2px 0 0 var(--border)) drop-shadow(-2px 0 0 var(--border))
    drop-shadow(0 2px 0 var(--border)) drop-shadow(0 -2px 0 var(--border))
    drop-shadow(1.4px 1.4px 0 var(--border)) drop-shadow(-1.4px 1.4px 0 var(--border))
    drop-shadow(1.4px -1.4px 0 var(--border)) drop-shadow(-1.4px -1.4px 0 var(--border));
}

.quote-header {
  font-size: 21px;
  font-weight: 800;
  color: var(--ink);
  line-height: 1.35;
  max-width: 280px;
  margin: 14px auto 0;
}

.info-list {
  list-style: none;
  padding: 0;
}
.info-list li {
  margin-bottom: 13px;
  padding-bottom: 13px;
  border-bottom: var(--border-w) dashed rgba(0, 0, 0, 0.18);
  font-size: 15px;
  display: flex;
  align-items: center;
}
.info-list li:last-child {
  border-bottom: none;
}
.info-list li i {
  font-size: 17px;
  width: 30px;
  color: var(--ink);
}
.info-list li strong {
  color: var(--ink);
  font-weight: 800;
  width: 140px;
  display: inline-block;
}
.info-list li span,
.info-list li a {
  color: var(--ink-muted);
  font-weight: 600;
}
.link-glow:hover {
  color: var(--ink) !important;
  background: var(--accent-2);
  box-shadow: 0 2px 0 0 var(--border);
}

@media (max-width: 767px) {
  .info-list li {
    flex-wrap: wrap;
  }
  .info-list li strong {
    width: 100%;
    margin-bottom: 2px;
  }
}

/* ==========================================================================
   EXPERIENCE — CAREER SEASONS TIMELINE
   ========================================================================== */

.experience {
  padding: 96px 0;
  position: relative;
  border-top: var(--border-w-thick) solid var(--border);
}

.timeline {
  position: relative;
  max-width: 880px;
  margin: 0 auto;
}
.timeline::before {
  content: '';
  position: absolute;
  width: var(--border-w-thick);
  background: var(--border);
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}

.timeline-item {
  position: relative;
  margin-bottom: 46px;
  width: 50%;
  padding: 0 40px;
}
.timeline-item:nth-child(even) {
  left: 50%;
}
.timeline-item:nth-child(odd) {
  left: 0;
}

.timeline-icon {
  position: absolute;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--surface);
  border: var(--border-w-thick) solid var(--border);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 15px;
  top: 14px;
  z-index: 10;
}
.timeline-item:nth-child(odd) .timeline-icon {
  right: -21px;
}
.timeline-item:nth-child(even) .timeline-icon {
  left: -21px;
}

.timeline-content {
  position: relative;
}

.season-badge {
  display: inline-block;
  padding: 4px 11px;
  background: var(--surface-alt);
  border: var(--border-w) solid var(--border);
  border-radius: 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 12px;
  color: var(--ink);
}
.season-badge.active-season {
  background: var(--main);
  box-shadow: var(--shadow-sm);
}

.timeline-content.season-card-active {
  background: var(--accent-2);
}

.role-title {
  font-size: 23px;
  font-weight: 900;
  color: var(--ink);
  margin-bottom: 6px;
}
.company-name {
  display: inline-block;
  font-size: 14px;
  font-weight: 800;
  color: var(--ink);
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: 4px;
  padding: 2px 8px;
  margin-bottom: 15px;
}
.company-name i {
  font-size: 13px;
}

.work-bullets {
  padding-left: 18px;
  margin: 0;
  font-size: 14px;
  color: var(--ink-muted);
}
.work-bullets li {
  margin-bottom: 8px;
  line-height: 1.55;
}
.work-bullets strong {
  color: var(--ink);
  font-weight: 800;
}

/* Kick-off marker */
.timeline-item .start-icon {
  background: var(--green) !important;
}
.timeline-item .start-content {
  padding: 16px;
  border-radius: var(--radius);
  background: var(--surface);
  border: var(--border-w) dashed var(--border);
}
.timeline-item .start-content h4 {
  font-size: 17px;
  color: var(--ink);
  font-weight: 900;
  margin-bottom: 3px;
}
.timeline-item .start-content p {
  font-size: 13px;
  color: var(--ink-muted);
  margin: 0;
}

@media (max-width: 768px) {
  .timeline::before {
    left: 20px;
  }
  .timeline-item {
    width: 100%;
    padding: 0 0 0 52px;
    left: 0 !important;
  }
  .timeline-icon {
    left: 0 !important;
    right: auto !important;
  }
  .timeline-item .start-content {
    text-align: left !important;
  }
}

/* ==========================================================================
   SKILLS
   ========================================================================== */

.skills {
  padding: 96px 0;
  position: relative;
  border-top: var(--border-w-thick) solid var(--border);
}

.skill-group-card {
  height: 100%;
  overflow: hidden;
}
.skill-group-card.active-group {
  background: var(--surface);
}

/* Coloured header band that bleeds to the card edges */
.skill-group-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: -28px -28px 24px;
  padding: 14px 24px;
  border-bottom: var(--border-w) solid var(--border);
}
.skill-group-header i {
  font-size: 22px;
  color: var(--ink);
}
.skill-group-header h3 {
  font-size: 17px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}

/* One flat colour per squad line */
.striker-header {
  background: var(--main);
}
.midfielder-header {
  background: var(--accent-3);
}
.defense-header {
  background: var(--accent-2);
}

.skill-items {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.skill-name {
  font-size: 14px;
  font-weight: 800;
  color: var(--ink);
  margin-bottom: 7px;
}

.skill-bar {
  width: 100%;
  height: 16px;
  background: var(--surface-alt);
  border: var(--border-w) solid var(--border);
  border-radius: 3px;
  overflow: hidden;
}

.skill-level {
  height: 100%;
  background: var(--ink-muted);
  border-right: var(--border-w) solid var(--border);
  transition: width 1s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.striker-header ~ .skill-items .skill-level {
  background: var(--main);
}
.midfielder-header ~ .skill-items .skill-level {
  background: var(--accent-3);
}
.defense-header ~ .skill-items .skill-level {
  background: var(--accent-2);
}

/* ==========================================================================
   TROPHY ROOM — PROJECT GALLERY
   ========================================================================== */

.gallery {
  padding: 96px 0;
  position: relative;
  border-top: var(--border-w-thick) solid var(--border);
}

.trophy-filters {
  padding-bottom: 8px;
}
.filter-btn {
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
  padding: 9px 16px;
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--transition-smooth);
}
.filter-btn:hover {
  background: var(--accent-2);
}
.filter-btn.active {
  background: var(--main);
  box-shadow: var(--shadow);
}

/* Project cards */
.gallery-item {
  position: relative;
  overflow: hidden;
  height: 100%;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: var(--transition-smooth);
}
.gallery-item:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 0 var(--border);
}

.gallery-img-container {
  overflow: hidden;
  position: relative;
  aspect-ratio: 16/10;
  border-bottom: var(--border-w) solid var(--border);
}
.gallery-img-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease-out;
}

.gallery-links {
  position: absolute;
  inset: 0;
  background: var(--main-overlay);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  opacity: 0;
  transition: var(--transition-smooth);
  z-index: 5;
}
.gallery-links a {
  width: 46px;
  height: 46px;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  color: var(--ink);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
  transition: var(--transition-smooth);
}
.gallery-links a:hover {
  background: var(--accent-2);
  color: var(--ink);
}

.gallery-item:hover .gallery-img-container img {
  transform: scale(1.05);
}
.gallery-item:hover .gallery-links {
  opacity: 1;
}

.gallery-info {
  padding: 18px;
}
.project-category {
  display: inline-block;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
  background: var(--accent-2);
  border: var(--border-w) solid var(--border);
  border-radius: 3px;
  padding: 2px 7px;
  margin-bottom: 10px;
}
.project-title {
  font-size: 19px;
  font-weight: 900;
  color: var(--ink);
  margin-bottom: 8px;
}
.project-desc {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-muted);
  margin-bottom: 14px;
}

.tech-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tech-badge {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  background: var(--surface-alt);
  border: var(--border-w) solid var(--border);
  border-radius: 3px;
  color: var(--ink);
}

/* GLightbox overrides */
.glightbox-clean .gslide-description {
  background: var(--surface) !important;
  border-top: var(--border-w-thick) solid var(--border);
}
.glightbox-clean .gslide-title {
  color: var(--ink) !important;
  font-weight: 900;
}

/* ==========================================================================
   FOOTER
   ========================================================================== */

.footer {
  padding: 40px 0;
  background: var(--main);
  border-top: var(--border-w-thick) solid var(--border);
  position: relative;
}
.footer-bug-logo i {
  font-size: 26px;
}
.text-glow-red {
  color: var(--ink);
  display: inline-block;
}
.footer .copyright {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.footer .copyright strong {
  font-weight: 900;
}
.footer .credits {
  font-size: 12px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.7);
}

/* ==========================================================================
   SCROLL-TOP BUTTON
   ========================================================================== */

.scroll-top {
  position: fixed;
  visibility: hidden;
  opacity: 0;
  right: 20px;
  bottom: -20px;
  z-index: 999;
  background: var(--main);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  width: 44px;
  height: 44px;
  transition:
    opacity 0.2s ease-out,
    bottom 0.2s ease-out,
    transform 0.12s ease-out,
    background 0.12s ease-out,
    box-shadow 0.12s ease-out;
}
.scroll-top i {
  font-size: 22px;
  color: var(--ink);
  line-height: 0;
}
.scroll-top:hover {
  background: var(--accent-2);
}
.scroll-top.active {
  visibility: visible;
  opacity: 1;
  bottom: 20px;
}

/* ==========================================================================
   PRELOADER
   ========================================================================== */

#preloader {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99999;
  background: var(--background);
  display: flex;
  justify-content: center;
  align-items: center;
  transition: opacity 0.4s ease;
}
.spidey-loader {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.web-spinner {
  width: 76px;
  height: 76px;
  border: 5px solid var(--border);
  border-top-color: var(--main);
  border-radius: 50%;
  animation: spinLoader 1s linear infinite;
}
.loader-bug {
  position: absolute;
  top: 24px;
  font-size: 28px;
  color: var(--main);
}
.loader-bug {
  filter:
    drop-shadow(1px 0 0 var(--border)) drop-shadow(-1px 0 0 var(--border))
    drop-shadow(0 1px 0 var(--border)) drop-shadow(0 -1px 0 var(--border));
}
.loader-text {
  font-size: 15px;
  font-weight: 900;
  color: var(--ink);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: var(--accent-2);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 6px 14px;
  margin-top: 22px;
}

@keyframes spinLoader {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* ==========================================================================
   SPIDER-SENSE MODE — THEME CYCLER
   ========================================================================== */

/* Swatch inside the button, showing the theme that is currently applied */
.theme-swatch {
  width: 16px;
  height: 16px;
  border: var(--border-w) solid var(--border);
  border-radius: 3px;
  background: var(--main);
  flex: none;
}

/* Toast confirming the swap */
.theme-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(12px);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  background: var(--surface);
  border: var(--border-w-thick) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 100000;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  opacity: 0;
  transition:
    opacity 0.18s ease-out,
    transform 0.18s ease-out;
}
.theme-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.theme-toast i {
  font-size: 16px;
}
.theme-toast-swatches {
  display: flex;
  gap: 5px;
}
.theme-toast-swatches span {
  width: 15px;
  height: 15px;
  border: var(--border-w) solid var(--border);
  border-radius: 3px;
}
.theme-toast-swatches span:nth-child(1) {
  background: var(--main);
}
.theme-toast-swatches span:nth-child(2) {
  background: var(--accent-2);
}
.theme-toast-swatches span:nth-child(3) {
  background: var(--accent-3);
}

@media (max-width: 575px) {
  .theme-toast {
    font-size: 11px;
    padding: 10px 14px;
    gap: 9px;
  }
}

/* ==========================================================================
   REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
