/* Self-hosted Inter: a single variable font file covering weights 100-900. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =========================================================================
   GLASSMORPHISM DESIGN SYSTEM
   Two layers: a vivid ambient canvas (.ambient) and frosted panels that sit
   on top of it. Every glass value is a token so the light and dark themes
   stay in sync.
   ========================================================================= */

:root {
  color-scheme: dark;

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Canvas */
  --canvas: #04120a;
  --canvas-veil: rgba(4, 18, 10, 0.35);

  /* Type */
  --text-primary: #f2f8f4;
  --text-secondary: #b7cec1;
  --text-muted: #87a394;

  /* Glass surfaces */
  --glass-bg: rgba(255, 255, 255, 0.06);
  --glass-bg-hover: rgba(255, 255, 255, 0.11);
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-border-hover: rgba(255, 255, 255, 0.34);
  --glass-rim: rgba(255, 255, 255, 0.2); /* inner top highlight */
  --glass-specular: rgba(255, 255, 255, 0.55); /* crisp edge-light streak */
  --glass-shadow: 0 24px 50px -26px rgba(2, 4, 20, 0.95);
  --glass-shadow-hover: 0 34px 64px -26px rgba(2, 4, 20, 1);
  /* Hairlines that must stay visible against the canvas, not the glass. */
  --hairline: rgba(255, 255, 255, 0.28);

  /* Chips, pills, icon wells */
  --chip-bg: rgba(255, 255, 255, 0.07);
  --chip-border: rgba(255, 255, 255, 0.14);

  /* Accents */
  --accent: #b8dd6b;
  --accent-strong: #9ccb3b;
  --accent-soft: rgba(156, 203, 59, 0.16);
  --accent-gradient: linear-gradient(120deg, #b8dd6b 0%, #34d399 52%, #9ccb3b 100%);
  --accent-glow: 0 0 34px -6px rgba(156, 203, 59, 0.55);
  --accent-ring: rgba(184, 221, 107, 0.3);

  --ease-glass: cubic-bezier(0.16, 1, 0.3, 1);
}

html.light {
  color-scheme: light;

  --canvas: #edf3ee;
  --canvas-veil: rgba(255, 255, 255, 0.28);

  --text-primary: #0c1a12;
  --text-secondary: #3d5a49;
  --text-muted: #5b7263;

  /* Light glass is brighter and less transparent so text stays readable
     over the saturated orbs beneath it. */
  --glass-bg: rgba(255, 255, 255, 0.52);
  --glass-bg-hover: rgba(255, 255, 255, 0.68);
  --glass-border: rgba(255, 255, 255, 0.75);
  --glass-border-hover: rgba(255, 255, 255, 0.95);
  --glass-rim: rgba(255, 255, 255, 0.9);
  --glass-specular: rgba(255, 255, 255, 1);
  --glass-shadow: 0 24px 50px -28px rgba(20, 65, 45, 0.45);
  --glass-shadow-hover: 0 34px 64px -28px rgba(20, 65, 45, 0.55);
  --hairline: rgba(10, 40, 25, 0.16);

  --chip-bg: rgba(255, 255, 255, 0.55);
  --chip-border: rgba(255, 255, 255, 0.85);

  --accent: #0e8a5f;
  --accent-strong: #006747;
  --accent-soft: rgba(0, 103, 71, 0.12);
  --accent-gradient: linear-gradient(120deg, #006747 0%, #2f9e6b 52%, #6da51f 100%);
  --accent-glow: 0 0 34px -8px rgba(0, 103, 71, 0.4);
  --accent-ring: rgba(14, 138, 95, 0.3);
}

/* --- Base ---------------------------------------------------------------- */
* {
  box-sizing: border-box;
}

html {
  /* The rotating orbit rings have a bounding box wider than the ring
     itself, which would otherwise open a sideways scroll on phones. */
  overflow-x: clip;
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  min-height: 100vh;
  overflow-x: clip;
  font-family: var(--font-sans);
  line-height: 1.6;
  background-color: var(--canvas);
  color: var(--text-primary);
  transition: background-color 0.5s var(--ease-glass), color 0.5s var(--ease-glass);
}

::selection {
  background-color: var(--accent);
  color: var(--canvas);
}

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

/* --- Core frosted surface ------------------------------------------------- */
.glass {
  background-color: var(--glass-bg);
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-rim);
}

/* --- Interactive glass card ----------------------------------------------- */
.glass-card {
  position: relative;
  overflow: hidden;
  background-color: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: 1.5rem;
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-rim);
  transition: transform 0.45s var(--ease-glass), background-color 0.45s var(--ease-glass),
    border-color 0.45s var(--ease-glass), box-shadow 0.45s var(--ease-glass);
}

/* Specular streak along the top edge — the tell of a real glass pane. */
.glass-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 1.75rem;
  right: 1.75rem;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--glass-specular), transparent);
  opacity: 0.75;
  transition: opacity 0.45s var(--ease-glass);
  pointer-events: none;
}

/* Light bloom that fades in behind the top-right corner on hover. */
.glass-card::after {
  content: "";
  position: absolute;
  top: -45%;
  right: -30%;
  width: 22rem;
  height: 22rem;
  background: radial-gradient(circle, var(--accent-soft) 0%, transparent 68%);
  opacity: 0;
  transition: opacity 0.45s var(--ease-glass);
  pointer-events: none;
}

/* Hover effects are gated to real pointers. On iOS a hover rule makes the
   first tap apply the hover state instead of activating the link, so the
   cards would need tapping twice. */
@media (hover: hover) and (pointer: fine) {
  .glass-card:hover {
    transform: translateY(-3px);
    background-color: var(--glass-bg-hover);
    border-color: var(--glass-border-hover);
    box-shadow: var(--glass-shadow-hover), inset 0 1px 0 var(--glass-rim), var(--accent-glow);
  }

  .glass-card:hover::before {
    opacity: 1;
  }

  .glass-card:hover::after {
    opacity: 1;
  }

  .glass-card:hover .icon-well {
    transform: translateY(-2px);
    background-color: var(--accent-soft);
  }

  .glass-card:hover .link-badge {
    color: var(--accent-strong);
  }

  .glass-card:hover .link-action svg {
    transform: translateX(0.25rem);
  }
}

/* Touch feedback, since there is no hover to preview the press. */
.glass-card:active {
  background-color: var(--glass-bg-hover);
  border-color: var(--glass-border-hover);
}

/* --- Small frosted pieces: pills, badges, icon wells ----------------------- */
.glass-chip {
  background-color: var(--chip-bg);
  border: 1px solid var(--chip-border);
  backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  box-shadow: inset 0 1px 0 var(--glass-rim);
  transition: background-color 0.45s var(--ease-glass), border-color 0.45s var(--ease-glass),
    color 0.45s var(--ease-glass), transform 0.45s var(--ease-glass);
}

.glass-button {
  background-color: var(--chip-bg);
  border: 1px solid var(--chip-border);
  backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  box-shadow: inset 0 1px 0 var(--glass-rim);
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color 0.35s var(--ease-glass), border-color 0.35s var(--ease-glass),
    transform 0.35s var(--ease-glass), box-shadow 0.35s var(--ease-glass);
}

@media (hover: hover) and (pointer: fine) {
  .glass-button:hover {
    background-color: var(--glass-bg-hover);
    border-color: var(--glass-border-hover);
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 var(--glass-rim), var(--accent-glow);
  }
}

.glass-button:active {
  background-color: var(--glass-bg-hover);
  border-color: var(--glass-border-hover);
}

/* --- Gradient text --------------------------------------------------------- */
.text-gradient {
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* --- Hairline divider between sections ------------------------------------- */
.glass-divider {
  height: 1px;
  margin: 3rem 0;
  background: linear-gradient(
    90deg,
    transparent,
    var(--hairline) 18%,
    var(--hairline) 82%,
    transparent
  );
}

@media (min-width: 768px) {
  .glass-divider {
    margin: 4rem 0;
  }
}

/* =========================================================================
   AMBIENT CANVAS
   Slowly drifting gradient orbs plus a grain and dot-grid overlay. Fixed to
   the viewport and non-interactive.
   ========================================================================= */
.ambient {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Base wash — a wide mesh gradient behind everything else. On phones this
   one element carries the whole canvas: the orb colours are baked into it
   as extra stops (see the phone media block below). */
.mesh-wash {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(ellipse 90% 70% at 15% 0%, rgba(52, 211, 153, 0.3), transparent 60%),
    radial-gradient(ellipse 80% 60% at 85% 15%, rgba(163, 230, 53, 0.26), transparent 60%),
    radial-gradient(ellipse 90% 70% at 50% 100%, rgba(20, 184, 166, 0.22), transparent 65%);
}

.orb {
  position: absolute;
  border-radius: 9999px;
  filter: blur(90px);
  /* No will-change: it pins five ~600px blurred layers in GPU memory for
     the life of the page, which is more than a phone should carry. The
     compositor promotes them while the transform animation runs anyway. */
}

.orb-a {
  top: -10rem;
  left: -8rem;
  height: 34rem;
  width: 34rem;
  background-color: rgba(52, 211, 153, 0.35);
}

.orb-b {
  top: -6rem;
  right: -10rem;
  height: 30rem;
  width: 30rem;
  background-color: rgba(22, 163, 74, 0.35);
}

.orb-c {
  top: 38%;
  left: 45%;
  height: 26rem;
  width: 26rem;
  background-color: rgba(163, 230, 53, 0.22);
}

.orb-d {
  bottom: -12rem;
  left: -6rem;
  height: 32rem;
  width: 32rem;
  background-color: rgba(45, 212, 191, 0.28);
}

.orb-e {
  right: -8rem;
  bottom: -10rem;
  height: 28rem;
  width: 28rem;
  background-color: rgba(5, 150, 105, 0.3);
}

/* Veil knocks the saturation back so body text stays readable. */
.veil {
  position: absolute;
  inset: 0;
  background-color: var(--canvas-veil);
}

/* Fine film grain keeps the large blurred gradients from banding. */
.grain {
  position: absolute;
  inset: 0;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Faint scientific dot grid, carried over from the original design. */
.dot-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(var(--hairline) 1px, transparent 1px);
  background-size: 32px 32px;
  opacity: 0.5;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 40%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 40%, transparent 100%);
}

/* =========================================================================
   LAYOUT
   ========================================================================= */
.layout {
  position: relative;
  z-index: 10;
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

.main {
  margin: 0 auto;
  width: 100%;
  max-width: 1200px;
  flex: 1;
  padding: 0 1.5rem;
}

/* --- Header ---------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-left: 0;
  border-right: 0;
  border-top: 0;
}

.header-inner {
  margin: 0 auto;
  display: flex;
  height: 5rem;
  width: 100%;
  max-width: 1200px;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 1.5rem;
}

.logo {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
}

.logo-mark {
  display: flex;
  height: 2.25rem;
  width: 2.25rem;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 0.75rem;
  color: #fff;
  background: var(--accent-gradient);
  box-shadow: 0 8px 24px -8px rgba(156, 203, 59, 0.85);
}

.logo-text {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

@media (min-width: 640px) {
  .logo-text {
    font-size: 1.15rem;
  }
}

.theme-toggle {
  display: flex;
  height: 2.75rem;
  width: 2.75rem;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
}

/* Moon shows in dark mode, sun in light mode. */
.theme-toggle .icon-sun {
  display: none;
}

html.light .theme-toggle .icon-sun {
  display: block;
}

html.light .theme-toggle .icon-moon {
  display: none;
}

/* --- Hero ------------------------------------------------------------------- */
.hero {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: 3.5rem;
  padding: 4rem 0;
}

/* Portrait sits first on mobile, second on desktop. */
.hero-portrait {
  order: -1;
}

@media (min-width: 768px) {
  .hero {
    grid-template-columns: 1.25fr 0.75fr;
    padding: 6rem 0;
  }

  .hero-portrait {
    order: 1;
  }
}

.hero-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  animation-delay: 0.1s;
}

@media (min-width: 768px) {
  .hero-content {
    align-items: flex-start;
    text-align: left;
  }
}

.hero-chip {
  margin-bottom: 1.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: 9999px;
  padding: 0.5rem 1rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-strong);
}

.hero-title {
  margin: 0 0 1rem;
  font-size: 2.5rem;
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.03em;
}

@media (min-width: 1024px) {
  .hero-title {
    font-size: 3.5rem;
  }
}

.hero-subtitle {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--accent-strong);
}

.hero-role {
  margin: 0 0 2.5rem;
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--text-secondary);
}

.bio-card {
  width: 100%;
  padding: 1.75rem;
}

.bio-card p {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.8;
  color: var(--text-secondary);
}

.bio-card strong {
  font-weight: 600;
  color: var(--text-primary);
}

@media (min-width: 768px) {
  .bio-card {
    padding: 2rem;
  }

  .bio-card p {
    text-align: justify;
  }
}

/* --- Subpage hero -------------------------------------------------------------- */
.page-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 4rem 0 3rem;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 2rem;
  border-radius: 9999px;
  padding: 0.625rem 1.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

.page-title {
  margin: 0;
  max-width: 60rem;
  font-size: 2rem;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.03em;
}

@media (min-width: 1024px) {
  .page-title {
    font-size: 2.75rem;
  }
}

/* --- Portrait ---------------------------------------------------------------- */
.portrait {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.portrait-frame {
  position: relative;
  display: flex;
  height: 17.5rem;
  width: 17.5rem;
  align-items: center;
  justify-content: center;
}

/* Orbiting vector rings */
.portrait-ring-dashed {
  pointer-events: none;
  position: absolute;
  height: 20.5rem;
  width: 20.5rem;
  border-radius: 9999px;
  border: 1px dashed var(--hairline);
}

.portrait-ring-dotted {
  pointer-events: none;
  position: absolute;
  height: 18.75rem;
  width: 18.75rem;
  border-radius: 9999px;
  border: 1px dotted var(--accent-ring);
}

/* Glass lens holding the portrait */
.portrait-lens {
  position: relative;
  z-index: 10;
  height: 100%;
  width: 100%;
  border-radius: 9999px;
  padding: 1px;
  box-shadow: 0 24px 50px -20px rgba(2, 4, 20, 0.8);
  transition: transform 0.5s var(--ease-glass), box-shadow 0.5s var(--ease-glass);
}

.portrait-lens:hover {
  transform: translateY(-0.25rem);
  box-shadow: 0 30px 60px -20px var(--accent-soft);
}

.portrait-ring-gradient {
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  opacity: 0.4;
  background: var(--accent-gradient);
  transition: opacity 0.5s var(--ease-glass);
}

.portrait-lens:hover .portrait-ring-gradient {
  opacity: 1;
}

.portrait-lens-inner {
  position: relative;
  display: flex;
  height: 100%;
  width: 100%;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 9999px;
  border: 1px solid var(--glass-border);
  background-color: var(--glass-bg);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
}

.portrait-lens-inner img {
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

.portrait-badge {
  position: absolute;
  bottom: -0.75rem;
  z-index: 20;
  border-radius: 1rem;
  padding: 0.375rem 1.25rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #fff;
  background: var(--accent-gradient);
  box-shadow: 0 10px 24px -8px rgba(0, 103, 71, 0.8);
}

/* CSS/SVG artwork shown if the headshot fails to load. */
.portrait-artwork {
  display: none;
}

.portrait-lens-inner.image-failed img {
  display: none;
}

.portrait-lens-inner.image-failed .portrait-artwork {
  position: relative;
  display: flex;
  height: 100%;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle, var(--accent-soft) 0%, transparent 70%);
}

.artwork-cross {
  position: absolute;
  height: 50%;
  width: 50%;
  opacity: 0.1;
}

.artwork-node {
  position: absolute;
  height: 0.375rem;
  width: 0.375rem;
  border-radius: 9999px;
  background-color: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}

.node-1 {
  top: 25%;
  left: 30%;
}

.node-2 {
  top: 40%;
  right: 25%;
  animation-delay: 0.5s;
}

.node-3 {
  bottom: 30%;
  left: 45%;
  animation-delay: 1s;
}

.artwork-person {
  position: relative;
  z-index: 10;
  color: var(--accent-strong);
  filter: drop-shadow(0 0 15px var(--accent-soft));
}

.artwork-person svg {
  height: 4.5rem;
  width: 4.5rem;
}

/* --- Section label ----------------------------------------------------------- */
.section-label {
  margin: 0 0 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--accent-strong);
}

.label-line {
  height: 1px;
  width: 2rem;
  background-color: currentColor;
  opacity: 0.4;
}

/* --- Pillars ------------------------------------------------------------------ */
.pillars-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

@media (min-width: 768px) {
  .pillars-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1024px) {
  .pillars-grid {
    gap: 2rem;
  }
}

.pillar-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 2.25rem;
  /* The AI Education pillar is an <a>; the other two are <article>. */
  color: inherit;
  text-decoration: none;
}

/* Pinned to the bottom so the cue lines up whatever the card's text length. */
.pillar-card .link-action {
  margin-top: auto;
  padding-top: 1.75rem;
}

@media (min-width: 1024px) {
  .pillar-card {
    padding: 2.5rem;
  }
}

.icon-well {
  display: flex;
  height: 3rem;
  width: 3rem;
  align-items: center;
  justify-content: center;
  border-radius: 0.75rem;
  color: var(--accent-strong);
}

.pillar-card .icon-well {
  margin-bottom: 1.75rem;
}

.pillar-card h3 {
  margin: 0 0 0.75rem;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

.pillar-card p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.625;
  color: var(--text-secondary);
}

/* --- Curated links ------------------------------------------------------------ */
.links-section {
  margin-bottom: 5rem;
}

/* The USF faculty section (.featured-grid) shares this layout. */
.links-grid,
.featured-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

@media (min-width: 768px) {
  .links-grid,
  .featured-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .links-grid,
  .featured-grid {
    gap: 2rem;
  }
}

.link-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 2rem;
  color: inherit;
  text-decoration: none;
}

@media (min-width: 1024px) {
  .link-card {
    padding: 2.5rem;
  }
}

.link-head {
  margin-bottom: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.link-badge {
  border-radius: 1rem;
  padding: 0.375rem 0.875rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.link-body {
  margin-bottom: 2rem;
}

.link-body h3 {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

.link-body p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.625;
  color: var(--text-secondary);
}

.link-action {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-strong);
}

.link-action svg {
  transition: transform 0.5s var(--ease-glass);
}

/* --- Footer -------------------------------------------------------------------- */
.site-footer {
  margin-top: auto;
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  padding: 3rem 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.footer-inner {
  margin: 0 auto;
  display: flex;
  width: 100%;
  max-width: 1200px;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding: 0 1.5rem;
  text-align: center;
}

@media (min-width: 768px) {
  .footer-inner {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

.footer-copy {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.footer-copy p {
  margin: 0;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
}

.footer-links a {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  padding: 0 0.25rem;
  color: inherit;
  text-decoration: none;
  transition: color 0.3s;
}

@media (hover: hover) and (pointer: fine) {
  .footer-links a:hover {
    color: var(--accent-strong);
  }
}

.to-top {
  display: flex;
  height: 2.75rem;
  width: 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  padding: 0;
  color: var(--text-secondary);
  text-decoration: none;
}

/* -------------------------------------------------------------------------
   Phones and other touch devices.

   backdrop-filter is removed outright here rather than merely reduced.
   The background sits in a position:fixed layer, so on every scroll frame
   each frosted surface has to re-sample a backdrop that just moved — the
   cost scales with scrolling, which is why lowering the blur radius alone
   did not help. The panels compensate with more opaque fills.
   ------------------------------------------------------------------------- */
@media (max-width: 900px), (pointer: coarse) {
  :root {
    --glass-bg: rgba(255, 255, 255, 0.1);
    --glass-bg-hover: rgba(255, 255, 255, 0.14);
    --chip-bg: rgba(255, 255, 255, 0.12);
    --canvas-veil: rgba(4, 18, 10, 0.28);
    --surface-solid: #06140c;
  }

  html.light {
    --glass-bg: rgba(255, 255, 255, 0.75);
    --glass-bg-hover: rgba(255, 255, 255, 0.85);
    --chip-bg: rgba(255, 255, 255, 0.78);
    --canvas-veil: rgba(255, 255, 255, 0.45);
    --surface-solid: #eef5f0;
  }

  .glass,
  .glass-card,
  .glass-chip,
  .glass-button,
  .portrait-lens-inner {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* The header is the one surface with content moving underneath it, so
     without a blur to obscure them it needs a near-solid fill. */
  header.glass {
    background-color: var(--surface-solid);
  }

  /* The base mesh wash alone carries the look at phone size. Dropping the
     orbs removes five large blurred textures from GPU memory; the grain
     and dot grid each force an extra offscreen pass (blend group, mask). */
  .orb,
  .grain,
  .dot-grid {
    display: none;
  }

  /* Nothing should animate forever on a phone. */
  .animate-spin-cw,
  .animate-spin-ccw,
  .animate-pulse-node {
    animation: none !important;
  }

  /* The orbs' colour, painted into the wash as extra gradient stops. Soft
     stops imitate the blur, so the canvas stays vivid for one paint and
     no filter, no layer, no animation. */
  .mesh-wash {
    background-image: radial-gradient(70% 45% at 10% 4%, rgba(52, 211, 153, 0.5), transparent 72%),
      radial-gradient(65% 40% at 92% 14%, rgba(163, 230, 53, 0.45), transparent 72%),
      radial-gradient(60% 35% at 18% 46%, rgba(20, 184, 166, 0.34), transparent 72%),
      radial-gradient(65% 40% at 88% 66%, rgba(22, 163, 74, 0.42), transparent 72%),
      radial-gradient(70% 45% at 38% 96%, rgba(190, 242, 100, 0.3), transparent 72%) !important;
  }
}

/* --- Motion --------------------------------------------------------------- */
@keyframes drift-a {
  0% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  100% {
    transform: translate3d(6%, 8%, 0) scale(1.12);
  }
}

@keyframes drift-b {
  0% {
    transform: translate3d(0, 0, 0) scale(1.08);
  }
  100% {
    transform: translate3d(-8%, -6%, 0) scale(0.95);
  }
}

@keyframes drift-c {
  0% {
    transform: translate3d(0, 0, 0) scale(0.95);
  }
  100% {
    transform: translate3d(5%, -9%, 0) scale(1.15);
  }
}

@keyframes spin-cw {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes spin-ccw {
  from {
    transform: rotate(360deg);
  }
  to {
    transform: rotate(0deg);
  }
}

@keyframes pulse-node {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.4;
  }
  50% {
    transform: scale(1.5);
    opacity: 1;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-drift-a {
  animation: drift-a 22s var(--ease-glass) infinite alternate;
}
.animate-drift-b {
  animation: drift-b 26s var(--ease-glass) infinite alternate;
}
.animate-drift-c {
  animation: drift-c 30s var(--ease-glass) infinite alternate;
}
.animate-spin-cw {
  animation: spin-cw 34s linear infinite;
}
.animate-spin-ccw {
  animation: spin-ccw 44s linear infinite;
}
.animate-pulse-node {
  animation: pulse-node 3s ease-in-out infinite;
}
.animate-rise-in {
  animation: rise-in 0.7s var(--ease-glass) both;
}

@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;
  }
}
