/* ==========================================================================
   tide.css: Andrei Corduneanu portfolio, "Tide" direction
   --------------------------------------------------------------------------
   Colours, type and glass:   NBT Brand Book, Direction F "Tide"
   Motion, hover and scroll:  NBT Labs website (globals.css), same timings
   Background:                hex artwork, Tide Ink (default) or Fine Grid

   Sections
     1. Tokens (light / dark)          7. Project cards (spotlight + scrub)
     2. Base                           8. Hex hero + page backdrop (3 variants)
     3. Glass + pills                  9. Text animate / reveal / highlighter
     4. Header + mobile menu          10. Grid, ripple, scroll cue
     5. Buttons + links               11. Theme toggle + view transition
     6. Section scaffolding           12. Reduced motion
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* Tide palette: one blue family, from deep water to frost */
  --abyss: #071226;
  --navy: #0A1B3D;
  --deep: #0B3A8C;
  --cobalt: #1E5BFF;   /* action */
  --cobalt-ink: #1E4FD8; /* labels on light grounds */
  --azure: #3FA9F5;    /* light + glass */
  --sky: #9CC8FF;
  --ice: #CFE6FF;
  --mist: #DCE9FF;
  --frost: #F2F6FB;    /* light ground */
  --tide-gradient: linear-gradient(90deg, #071226, #1E5BFF 35%, #3FA9F5 65%, #CFE6FF 85%, #F2F6FB);

  /* Semantic, light theme */
  --bg: var(--frost);
  --bg-alt: #EEF3FA;
  --surface: rgba(255, 255, 255, .62);
  --text: var(--navy);
  --text-muted: #33415E;
  --label: var(--cobalt-ink);
  --line: #9DB4DA;
  --line-soft: rgba(10, 27, 61, .12);
  --highlight: var(--ice);
  --btn-bg: var(--cobalt);
  --btn-text: #FFFFFF;
  --btn-shimmer: var(--ice);
  --btn-arrow: #FFFFFF;
  --focus: var(--cobalt);

  --glass-bg: rgba(255, 255, 255, .38);
  --glass-border: rgba(255, 255, 255, .75);
  --glass-shadow: inset 0 1px 0 #FFFFFF, 0 24px 50px rgba(30, 70, 160, .16);
  --pill-border: #9DB4DA;

  --mesh:
    radial-gradient(ellipse 50% 60% at 100% 100%, #6FA8FF 0%, rgba(111, 168, 255, 0) 70%),
    radial-gradient(ellipse 40% 50% at 85% 0%, #BFDCFF 0%, rgba(191, 220, 255, 0) 70%),
    radial-gradient(ellipse 40% 40% at 0% 100%, #D6E6FF 0%, rgba(214, 230, 255, 0) 70%),
    #EEF3FA;
  --ribbon-a: linear-gradient(90deg, rgba(63, 169, 245, 0), #3FA9F5 40%, #CFE6FF 60%, rgba(30, 91, 255, 0));
  --ribbon-b: linear-gradient(90deg, rgba(30, 91, 255, 0), #1E5BFF 50%, rgba(30, 91, 255, 0));

  /* Layout (same rhythm as the NBT site) */
  --radius: 28px;          /* Tide: 28px radii */
  --radius-sm: 20px;
  --page: min(1280px, calc(100vw - 64px));
  --ease-out: cubic-bezier(.22, 1, .36, 1);

  --font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

html[data-theme="dark"] {
  color-scheme: dark;
  --bg: var(--abyss);
  --bg-alt: var(--navy);
  --surface: rgba(255, 255, 255, .05);
  --text: #FFFFFF;
  --text-muted: var(--mist);
  --label: var(--sky);
  --line: rgba(255, 255, 255, .28);
  --line-soft: rgba(255, 255, 255, .12);
  --highlight: rgba(30, 91, 255, .55);
  --btn-bg: #FFFFFF;
  --btn-text: var(--navy);
  --btn-shimmer: var(--cobalt);
  --btn-arrow: var(--cobalt);
  --focus: var(--azure);

  --glass-bg: rgba(255, 255, 255, .07);
  --glass-border: rgba(255, 255, 255, .28);
  --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 30px 60px rgba(4, 12, 40, .35);
  --pill-border: rgba(255, 255, 255, .55);

  --mesh:
    radial-gradient(ellipse 55% 55% at 78% 85%, #1E5BFF 0%, rgba(30, 91, 255, 0) 70%),
    radial-gradient(ellipse 35% 40% at 92% 25%, #3FA9F5 0%, rgba(63, 169, 245, 0) 70%),
    radial-gradient(ellipse 50% 60% at 10% 110%, #0B3A8C 0%, rgba(11, 58, 140, 0) 70%),
    #071226;
}

/* 2. Base ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 104px; /* anchors land below the fixed header */
  background: var(--bg);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  transition: background-color 300ms ease, color 300ms ease;
}

/* Fine grain over everything (NBT site detail), barely visible */
body::after {
  position: fixed;
  z-index: 9999;
  inset: 0;
  opacity: .03;
  pointer-events: none;
  content: "";
  background-image: radial-gradient(rgba(10, 27, 61, .7) .55px, transparent .7px);
  background-size: 4px 4px;
}

h1, h2, h3, h4 { margin: 0; font-weight: 500; letter-spacing: -.04em; line-height: 1; }
p { margin: 0; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; }
button { font: inherit; -webkit-tap-highlight-color: transparent; }
::selection { background: var(--cobalt); color: #FFFFFF; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 6px; }

.page-shell { position: relative; z-index: 1; overflow: clip; animation: page-enter 600ms var(--ease-out) both; }
@keyframes page-enter {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; z-index: 10000; top: 12px; left: 12px; padding: 12px 16px;
  transform: translateY(-180%); background: var(--cobalt); color: #FFFFFF;
  border-radius: 12px; font-weight: 700;
}
.skip-link:focus { transform: translateY(0); }

/* 3. Glass + pills (Tide: "glass cards on mesh, 28px radii, pill tags") ----- */
.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur, 24px)) saturate(140%);
  backdrop-filter: blur(var(--glass-blur, 24px)) saturate(140%);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border: 1px solid var(--pill-border);
  border-radius: 999px;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  white-space: nowrap;
}
.pill-solid { background: var(--cobalt); border-color: var(--cobalt); color: #FFFFFF; }

.eyebrow {
  margin: 0 0 22px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--label);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.eyebrow::before { width: 22px; height: 1px; background: var(--azure); content: ""; }

.mark-star { font-size: 1.1em; line-height: 1; } /* the Tide ✱ glyph */

/* 4. Header + mobile menu ---------------------------------------------------- */
.site-header { position: fixed; z-index: 1000; top: 16px; right: 0; left: 0; }

.header-shell {
  width: min(1280px, calc(100vw - 32px));
  min-height: 64px;
  margin: 0 auto;
  padding: 8px 8px 8px 18px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 22px;
  border-radius: 999px;
  transition: background-color 300ms ease, box-shadow 300ms ease;
}
.site-header.is-scrolled .header-shell { --glass-blur: 28px; }

.brand { display: inline-flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 600; letter-spacing: -.03em; white-space: nowrap; }
.brand-mark {
  width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 10px; background: var(--cobalt); color: #FFFFFF;
  font-family: var(--font-mono); font-size: 12px; font-weight: 700; letter-spacing: 0;
}

.desktop-nav { display: flex; justify-content: center; align-items: center; gap: clamp(14px, 2.4vw, 32px); }
.desktop-nav a { position: relative; color: var(--text-muted); font-size: 14px; transition: color 200ms ease; }
/* Underline that wipes in from the left (NBT site) */
.desktop-nav a::after {
  position: absolute; right: 0; bottom: -8px; left: 0; height: 1px;
  transform: scaleX(0); transform-origin: left; background: var(--azure);
  content: ""; transition: transform 260ms ease;
}
.desktop-nav a:hover, .desktop-nav a.is-active { color: var(--text); }
.desktop-nav a:hover::after, .desktop-nav a.is-active::after { transform: scaleX(1); }

.header-actions { display: flex; align-items: center; gap: 10px; }

.menu-toggle {
  width: 46px; height: 46px; display: none; align-content: center; justify-content: center; gap: 5px;
  border: 0; border-radius: 999px; background: var(--glass-bg); color: inherit; cursor: pointer;
}
.menu-toggle span { width: 18px; height: 1px; display: block; background: currentColor; transition: transform 220ms ease; }
.menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3px) rotate(-45deg); }

.mobile-menu {
  position: fixed; z-index: 990; inset: 0; display: none; padding: 112px 24px 28px;
  visibility: hidden; opacity: 0; background: var(--abyss); color: #FFFFFF;
  transition: opacity 250ms ease, visibility 250ms ease;
}
.mobile-menu.is-open { visibility: visible; opacity: 1; }
.mobile-menu nav { height: 100%; display: flex; flex-direction: column; }
.mobile-menu nav > a:not(.shimmer-button) {
  padding: 16px 0; display: flex; gap: 18px; align-items: baseline;
  border-bottom: 1px solid rgba(255, 255, 255, .14);
  font-size: clamp(28px, 8vw, 46px); font-weight: 500; letter-spacing: -.045em;
}
.mobile-menu nav > a:not(.shimmer-button) > span:first-child { color: var(--sky); font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; }
.mobile-menu .shimmer-button { margin-top: auto; }

@media (max-width: 900px) {
  .desktop-nav { display: none; }
  .menu-toggle { display: grid; }
  .mobile-menu { display: block; }
  .header-shell { grid-template-columns: 1fr auto; }
  .header-actions .shimmer-button { display: none; }
}

/* 5. Buttons + links (ShimmerButton / PulsatingButton / text-link) ----------- */
.shimmer-button {
  --shimmer-background: var(--btn-bg);
  --shimmer-color: var(--btn-shimmer);
  --shimmer-size: 2px;
  --shimmer-radius: 999px;
  --shimmer-duration: 3s;
  position: relative;
  isolation: isolate;
  min-height: 50px;
  padding: 0 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 0;
  border-radius: var(--shimmer-radius);
  background: color-mix(in srgb, var(--shimmer-background) 78%, var(--shimmer-color));
  color: var(--btn-text);
  box-shadow: 0 16px 40px rgba(10, 27, 61, .22), inset 0 0 0 1px rgba(255, 255, 255, .08);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.01em;
  transition: transform 220ms ease, box-shadow 220ms ease;
}
.shimmer-button-border {
  position: absolute; z-index: 0; top: 50%; left: 50%; width: 220%; aspect-ratio: 1;
  background: conic-gradient(from 0deg,
    transparent 0 41%,
    color-mix(in srgb, var(--shimmer-color) 35%, transparent) 45%,
    var(--shimmer-color) 49%,
    color-mix(in srgb, var(--shimmer-color) 35%, transparent) 53%,
    transparent 57% 100%);
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--shimmer-color) 70%, transparent));
  transform: translate(-50%, -50%) rotate(0turn);
  animation: shimmer-button-spin var(--shimmer-duration) linear infinite;
  pointer-events: none;
}
.shimmer-button-surface {
  position: absolute; z-index: 1; inset: var(--shimmer-size); overflow: hidden;
  border-radius: calc(var(--shimmer-radius) - var(--shimmer-size));
  background: linear-gradient(110deg, transparent 20%, rgba(255, 255, 255, .1) 48%, transparent 72%), var(--shimmer-background);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
  pointer-events: none;
}
.shimmer-button-content { position: relative; z-index: 2; display: inline-flex; align-items: center; justify-content: center; gap: 14px; white-space: nowrap; }
.shimmer-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 48px rgba(10, 27, 61, .3), 0 0 28px color-mix(in srgb, var(--shimmer-color) 22%, transparent);
}
@keyframes shimmer-button-spin { to { transform: translate(-50%, -50%) rotate(1turn); } }

/* Glass variant: secondary action on mesh */
.shimmer-button-glass { --shimmer-background: var(--glass-bg); --shimmer-color: var(--azure); color: var(--text); }

/* Drawn ↗ arrow that nudges on hover (identical geometry to the NBT site) */
.arrow { position: relative; width: 12px; height: 12px; display: inline-block; flex: 0 0 12px; color: var(--btn-arrow); transition: transform 220ms ease; }
.arrow::before { position: absolute; top: 0; right: 0; width: 7px; height: 7px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; content: ""; }
.arrow::after { position: absolute; top: 5.25px; left: 0; width: 11px; height: 1.5px; border-radius: 999px; background: currentColor; content: ""; transform: rotate(-45deg); }
a:hover > .arrow, button:hover > .arrow,
.shimmer-button:hover .arrow, .project-card:hover .arrow { transform: translate(2px, -2px); }

.pulsating-button {
  --pulse-color: var(--cobalt);
  position: relative; isolation: isolate; min-height: 54px; padding: 0 28px;
  display: inline-flex; align-items: center; justify-content: center; gap: 18px;
  border: 1.5px solid var(--pulse-color); border-radius: 999px;
  background: var(--btn-bg); color: var(--btn-text);
  box-shadow: 0 18px 46px rgba(30, 91, 255, .2), 0 8px 24px rgba(10, 27, 61, .14), inset 0 1px 0 rgba(255, 255, 255, .3);
  cursor: pointer; font-size: 15px; font-weight: 600; letter-spacing: -.015em;
  transition: transform 220ms ease, box-shadow 220ms ease;
}
.pulsating-button::before, .pulsating-button::after {
  position: absolute; z-index: -1; inset: -2px; border: 2px solid var(--pulse-color);
  border-radius: inherit; content: ""; opacity: 0; transform: scale(1);
  animation: pulsating-button-wave 2.8s cubic-bezier(.2, .7, .2, 1) infinite; pointer-events: none;
}
.pulsating-button::after { animation-delay: 1.4s; }
.pulsating-button:hover { transform: translateY(-3px) scale(1.015); box-shadow: 0 24px 60px rgba(30, 91, 255, .28), 0 10px 30px rgba(10, 27, 61, .16); }
@keyframes pulsating-button-wave {
  0% { opacity: .54; transform: scale(1); }
  72%, 100% { opacity: 0; transform: scale(1.22, 1.48); }
}

.text-link {
  width: fit-content; padding-bottom: 5px; display: inline-flex; align-items: center; gap: 10px;
  border-bottom: 1px solid currentColor; font-size: 14px; font-weight: 600; transition: gap 220ms ease;
}
.text-link:hover { gap: 15px; }
.text-link .arrow { color: currentColor; }

.button-row { display: flex; align-items: center; flex-wrap: wrap; gap: 24px; }

.icon-button {
  width: 46px; height: 46px; display: inline-grid; place-items: center;
  border-radius: 999px; color: var(--text); transition: transform 220ms ease, background-color 220ms ease;
}
.icon-button:hover { transform: translateY(-2px); }
.icon-button svg { width: 18px; height: 18px; }

/* 6. Section scaffolding ------------------------------------------------------ */
.section-pad { position: relative; width: var(--page); margin: 0 auto; padding: clamp(96px, 11vw, 160px) 0; }
.section-heading { max-width: 860px; margin-bottom: 56px; }
.section-heading h2 { font-size: clamp(42px, 5.6vw, 80px); letter-spacing: -.055em; line-height: .98; }
.section-heading p { margin-top: 22px; max-width: 620px; color: var(--text-muted); font-size: clamp(16px, 1.4vw, 19px); }
.section-index { color: var(--label); font-family: var(--font-mono); font-size: 12px; }
.lede { max-width: 640px; color: var(--text-muted); font-size: clamp(17px, 1.6vw, 21px); line-height: 1.55; }

/* 7. Project cards: spotlight tilt + scroll scrub ----------------------------- */
.project-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 1024px) { .project-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .project-grid { grid-template-columns: 1fr; } }

.project-card {
  --spotlight-x: 50%;
  --spotlight-y: 40%;
  --spotlight-opacity: 0;
  --spotlight-rotate-x: 0deg;
  --spotlight-rotate-y: 0deg;
  --spotlight-lift: 0px;
  --focus-opacity: 1;
  --focus-brightness: 1;
  --focus-saturation: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius);
  transform: perspective(900px) rotateX(var(--spotlight-rotate-x)) rotateY(var(--spotlight-rotate-y)) translateY(var(--spotlight-lift));
  transform-style: preserve-3d;
  transition: transform 280ms var(--ease-out), box-shadow 350ms ease, opacity 240ms ease, filter 240ms ease;
}
.project-card:hover, .project-card:focus-within { box-shadow: var(--glass-shadow), 0 34px 80px rgba(30, 70, 160, .22); }
/* Diagonal sheen that sweeps across on hover */
.project-card::before {
  position: absolute; z-index: 3; top: 0; bottom: 0; left: -60%; width: 42%;
  opacity: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .22), transparent);
  content: ""; transform: skewX(-14deg); transition: left 700ms ease, opacity 260ms ease;
}
.project-card[data-spotlight-active="true"]::before { left: 122%; opacity: .72; }
/* Cursor-following glow */
.project-card::after {
  position: absolute; z-index: 2; inset: 0; opacity: var(--spotlight-opacity); pointer-events: none;
  background: radial-gradient(circle at var(--spotlight-x) var(--spotlight-y), rgba(63, 169, 245, .28) 0%, transparent 48%);
  content: ""; transition: opacity 220ms ease;
}
[data-scrub="cards"] > .project-card {
  opacity: min(var(--card-scrub-opacity, 1), var(--focus-opacity, 1));
  filter: blur(var(--card-scrub-blur, 0px)) brightness(var(--focus-brightness, 1)) saturate(var(--focus-saturation, 1));
  translate: var(--card-scrub-x, 0px) var(--card-scrub-y, 0px);
  scale: var(--card-scrub-scale, 1);
  will-change: translate, scale, opacity, filter;
}
/* The other cards step back while one is focused */
[data-spotlight-active="true"] > .project-card:not([data-spotlight-active="true"]) {
  --focus-opacity: .58;
  --focus-brightness: .86;
  --focus-saturation: .72;
}

/* Mystery bubbles: at rest a card is only its image, framed like an art
   piece. The name surfaces on hover, keyboard focus, or (on touch screens)
   when the card reaches the middle of the viewport. The caption is always in
   the DOM, so screen readers and search engines still get the title. */
.project-media { position: relative; z-index: 1; margin: 10px; aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius-sm); background: var(--bg-alt); }
.project-media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.9);
  transition: transform 900ms var(--ease-out), filter 500ms ease;
}
.project-index { position: absolute; z-index: 3; top: 22px; left: 22px; background: var(--glass-bg); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); font-size: 11px; }
.project-caption {
  position: absolute; z-index: 3; right: 20px; bottom: 20px; left: 20px;
  padding: 16px 18px; display: flex; flex-direction: column; gap: 10px;
  border-radius: 18px;
  opacity: 0; filter: blur(8px); transform: translate3d(0, 18px, 0);
  transition: opacity 420ms ease, filter 420ms ease, transform 620ms var(--ease-out);
  pointer-events: none;
}
.project-caption h3 { padding-right: 26px; font-size: 20px; letter-spacing: -.03em; line-height: 1.12; }
.project-caption .arrow { position: absolute; top: 18px; right: 18px; color: var(--text); }
.project-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.project-tags .pill { font-size: 11px; padding: 3px 9px; }
.project-card > a.stretched { position: absolute; z-index: 4; inset: 0; border-radius: inherit; }

.project-card:hover .project-media img,
.project-card:focus-within .project-media img,
.project-card[data-spotlight-active="true"] .project-media img { transform: scale(1.06); filter: saturate(1.05) brightness(.82); }
.project-card:hover .project-caption,
.project-card:focus-within .project-caption,
.project-card[data-spotlight-active="true"] .project-caption { opacity: 1; filter: blur(0); transform: none; }

/* Stack variant (timeline / experience) */
.stack { display: grid; gap: 0; }
.stack > * {
  padding: 26px 0; display: grid; grid-template-columns: 180px 1fr; gap: 24px;
  border-top: 1px solid var(--line-soft);
  transition: transform 300ms var(--ease-out), background-color 300ms ease;
}
.stack > *:hover { transform: translateX(8px); }
[data-scrub="stack"] > * {
  opacity: var(--card-scrub-opacity, 1);
  filter: blur(var(--card-scrub-blur, 0px));
  translate: 0 var(--card-scrub-y, 0px);
  scale: var(--card-scrub-scale, 1);
}
@media (max-width: 700px) { .stack > * { grid-template-columns: 1fr; gap: 8px; } }

/* 8. Hex hero + page backdrop --------------------------------------------------
   Layers, back to front:
     .tide-mesh      Tide radial-gradient mesh
     .tide-ribbons   blurred "liquid light" ribbons
     .hex-layer      the hex artwork (variant-specific colour, opacity, blend)
     content         glass card / headline (sharp type on top)
   Default is TIDE INK. <html data-hex="fine"> switches to the alternative
   (it also works on a single section, which is how samples.html compares
   them). ------------------------------------------------------------------ */
:root {
  --hex-image: url("../img/hex-tide-ink.png");
  --hex-size: cover;
  --hex-position: right top;
  --hex-opacity: .3;
  --hex-blend: multiply;
  --hex-filter: none;
  --ribbon-blur: 26px;
  --ribbon-opacity: .7;
  --glass-blur: 24px;
  --page-hex-opacity: .07;
  --page-hex-size: 1100px auto;
}
/* Every variant restates the full set so a section never inherits another
   variant's values from <html>. */
/* DEFAULT · TIDE INK. Hex recoloured to deep navy; on dark it turns black
   and cuts across the glowing ribbons. Full Tide blur. */
[data-hex="ink"] {
  --hex-image: url("../img/hex-tide-ink.png");
  --hex-opacity: .3;
  --hex-blend: multiply;
  --hex-filter: none;
  --ribbon-blur: 26px;
  --ribbon-opacity: .7;
  --glass-blur: 24px;
  --page-hex-opacity: .07;
  --page-hex-size: 1100px auto;
}
[data-theme="dark"][data-hex="ink"],
[data-theme="dark"] [data-hex="ink"] {
  --hex-opacity: .62;
  --hex-blend: normal;
  --hex-filter: brightness(0);
  --ribbon-opacity: .95;
  --page-hex-opacity: .35;
}
/* ALTERNATIVE · FINE GRID. Smaller, denser hex texture that reads as background. */
[data-hex="fine"] {
  --hex-image: url("../img/hex-fine.png");
  --hex-opacity: .9;
  --hex-blend: normal;
  --hex-filter: none;
  --ribbon-blur: 22px;
  --ribbon-opacity: .45;
  --glass-blur: 16px;
  --page-hex-opacity: .2;
  --page-hex-size: 1400px auto;
}
[data-theme="dark"][data-hex="fine"],
[data-theme="dark"] [data-hex="fine"] {
  --hex-opacity: .75;
  --hex-blend: screen;
  --ribbon-opacity: .8;
}

.hex-hero {
  position: relative;
  isolation: isolate;
  min-height: clamp(640px, 88svh, 900px);
  padding: 150px max(32px, calc((100vw - 1280px) / 2)) 90px;
  display: grid;
  align-items: center;
  overflow: hidden;
  color: var(--text);
}
/* Project pages: same treatment, shorter (current site uses 67vh) */
.hex-hero.header-strip { min-height: clamp(520px, 67vh, 720px); align-items: end; }

.tide-mesh { position: absolute; z-index: -3; inset: 0; background: var(--mesh); }

.tide-ribbons { position: absolute; z-index: -2; inset: 0; pointer-events: none; opacity: var(--ribbon-opacity); }
.tide-ribbons i {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(var(--ribbon-blur));
  animation: ribbon-drift 18s ease-in-out infinite alternate;
}
.tide-ribbons i:nth-child(1) { left: 34%; top: 30%; width: 72vw; height: 22vw; max-height: 260px; background: var(--ribbon-a); transform: rotate(-22deg); }
.tide-ribbons i:nth-child(2) { left: 22%; top: 56%; width: 80vw; height: 18vw; max-height: 200px; background: var(--ribbon-b); transform: rotate(-14deg); animation-duration: 22s; animation-delay: -6s; }
@keyframes ribbon-drift {
  from { translate: -2vw 0; }
  to { translate: 3vw -2vw; }
}

.hex-layer {
  position: absolute; z-index: -1; inset: 0; pointer-events: none;
  background: var(--hex-image) var(--hex-position) / var(--hex-size) no-repeat;
  opacity: var(--hex-opacity);
  mix-blend-mode: var(--hex-blend);
  filter: var(--hex-filter);
  /* Same fade-out as the current site's "transparent 50% → white" gradient */
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 45%, transparent 96%);
}
/* Soft hand-off from hero into the page ground */
.hex-hero::after {
  position: absolute; z-index: -1; right: 0; bottom: 0; left: 0; height: 160px;
  background: linear-gradient(to bottom, transparent, var(--bg)); content: "";
}

/* Whole-page backdrop: faint fixed hex behind every section */
.page-backdrop {
  position: fixed; z-index: 0; inset: 0; pointer-events: none;
  background: var(--hex-image) right -120px top 20vh / var(--page-hex-size) no-repeat;
  opacity: var(--page-hex-opacity);
  mix-blend-mode: var(--hex-blend);
  filter: var(--hex-filter);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 80% 40%, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse 70% 60% at 80% 40%, #000 30%, transparent 75%);
}

.hero-grid { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: clamp(24px, 4vw, 64px); align-items: center; }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; } }

.hero-card { padding: clamp(24px, 3vw, 34px); border-radius: 30px; display: flex; flex-direction: column; gap: 26px; }
.hero-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.hero-card-top .tags { display: flex; gap: 8px; flex-wrap: wrap; }
.hero-title { font-size: clamp(56px, 8vw, 112px); letter-spacing: -.06em; line-height: .92; }
/* Applied to the split units too: background-clip:text does not reach
   transformed inline-block children, so each unit clips its own gradient. */
.gradient-word,
.gradient-word .text-animate-unit {
  background: linear-gradient(90deg, var(--cobalt), var(--azure) 60%, var(--sky));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; padding-top: 18px; border-top: 1px solid var(--line-soft); }
.hero-meta span { display: block; color: var(--label); font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.hero-meta strong { font-size: 15px; font-weight: 500; }
.hero-portrait { position: relative; justify-self: center; width: min(520px, 100%); }
.hero-portrait img {
  width: 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent);
  mask-image: linear-gradient(to bottom, #000 70%, transparent);
}

.hero-index {
  position: absolute; z-index: 2; right: max(32px, calc((100vw - 1280px) / 2)); bottom: 32px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
  color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; text-align: right;
}
.hero-index span:first-child { color: var(--text); font-size: 12px; font-weight: 700; }

/* 9. Text animate / viewport reveal / highlighter ----------------------------- */
.text-animate-word { display: inline-block; white-space: nowrap; }
.text-animate-unit { display: inline-block; opacity: 0; transition-delay: var(--text-animate-delay, 0s); }

.text-animate-blurInUp .text-animate-unit {
  filter: blur(10px); transform: translate3d(0, 20px, 0);
  transition-property: opacity, filter, transform;
  transition-duration: .4s, .3s, .3s;
  transition-timing-function: ease, ease, var(--ease-out);
}
.text-animate-slideUp .text-animate-unit {
  transform: translate3d(0, 1.05em, 0);
  transition: opacity .34s ease, transform .5s var(--ease-out);
  transition-delay: var(--text-animate-delay, 0s);
}
.text-animate-scaleUp .text-animate-unit {
  transform: scale(.72); transform-origin: 50% 65%;
  transition: opacity .34s ease, transform .52s var(--ease-out);
  transition-delay: var(--text-animate-delay, 0s);
}
.text-animate-fadeIn .text-animate-unit { transition: opacity .58s ease; transition-delay: var(--text-animate-delay, 0s); }
.text-animate-slideLeft .text-animate-unit {
  transform: translate3d(24px, 0, 0);
  transition: opacity .34s ease, transform .5s var(--ease-out);
  transition-delay: var(--text-animate-delay, 0s);
}
.text-animate-wavy .text-animate-unit {
  transform: translate3d(0, 30px, 0) rotate(45deg) scale(.5); transform-origin: 50% 80%;
  transition: opacity .4s ease, transform .65s cubic-bezier(.16, 1.46, .36, 1);
  transition-delay: var(--text-animate-delay, 0s);
}
.text-animate.is-visible .text-animate-unit { opacity: 1; filter: blur(0); transform: translate3d(0, 0, 0); }

.viewport-reveal {
  opacity: 0;
  filter: blur(8px);
  transform: translate3d(0, 30px, 0);
  transition:
    opacity .72s ease var(--viewport-reveal-delay, 0s),
    filter .62s ease var(--viewport-reveal-delay, 0s),
    transform .82s var(--ease-out) var(--viewport-reveal-delay, 0s),
    box-shadow .32s ease;
  will-change: opacity, filter, transform;
}
.viewport-reveal-scale { transform: scale(.965); transform-origin: 50% 60%; }
.viewport-reveal-left { transform: translate3d(34px, 0, 0); }
.viewport-reveal.is-visible { opacity: 1; filter: blur(0); transform: none; will-change: auto; }

.magic-highlighter { position: relative; z-index: 0; display: inline-block; isolation: isolate; white-space: nowrap; }
.magic-highlighter::before, .magic-highlighter::after {
  position: absolute; z-index: -1; pointer-events: none; background: var(--highlighter-color); content: "";
  transform-origin: left center; transition-property: transform, opacity;
  transition-duration: var(--highlighter-duration); transition-delay: var(--highlighter-delay);
  transition-timing-function: var(--ease-out);
}
.magic-highlighter[data-action="highlight"] { padding: 0 calc(var(--highlighter-padding) + .04em) .02em; }
.magic-highlighter[data-action="highlight"]::before {
  inset: .13em calc(var(--highlighter-padding) * -1) -.015em; opacity: .94;
  clip-path: polygon(1% 12%, 9% 5%, 23% 8%, 39% 2%, 57% 7%, 75% 3%, 98% 10%, 96% 87%, 85% 95%, 68% 91%, 49% 99%, 31% 93%, 12% 98%, 2% 88%);
  transform: scaleX(0) rotate(-.45deg);
}
.magic-highlighter[data-action="highlight"]::after {
  inset: .19em calc(var(--highlighter-padding) * -.45) .02em; opacity: .32;
  clip-path: polygon(0 15%, 14% 8%, 32% 12%, 51% 4%, 70% 10%, 100% 3%, 98% 90%, 78% 95%, 59% 88%, 38% 98%, 19% 91%, 2% 96%);
  transform: scaleX(0) rotate(.35deg); transition-delay: var(--highlighter-delay-secondary);
}
.magic-highlighter[data-action="underline"]::before, .magic-highlighter[data-action="underline"]::after {
  right: calc(var(--highlighter-padding) * -1); bottom: -.09em; left: calc(var(--highlighter-padding) * -1);
  height: max(var(--highlighter-stroke), .055em);
  clip-path: polygon(0 24%, 13% 10%, 27% 30%, 43% 4%, 61% 22%, 79% 8%, 100% 28%, 99% 78%, 82% 92%, 64% 72%, 47% 96%, 28% 76%, 11% 94%, 0 72%);
  transform: scaleX(0) rotate(-1deg);
}
.magic-highlighter[data-action="underline"]::after { bottom: -.13em; opacity: .55; transform: scaleX(0) rotate(.55deg); transition-delay: var(--highlighter-delay-secondary); }
.magic-highlighter.is-drawn::before { transform: scaleX(1) rotate(-.45deg); }
.magic-highlighter[data-action="highlight"].is-drawn::after { transform: scaleX(1) rotate(.35deg); }
.magic-highlighter[data-action="underline"].is-drawn::before { transform: scaleX(1) rotate(-1deg); }
.magic-highlighter[data-action="underline"].is-drawn::after { transform: scaleX(1) rotate(.55deg); }
/* Wait for the surrounding headline to appear before drawing */
.text-animate:not(.is-visible) .magic-highlighter::before,
.text-animate:not(.is-visible) .magic-highlighter::after { opacity: 0; }

/* 10. Animated grid, ripple, scroll cue ---------------------------------------- */
.magic-animated-grid {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  background-image: linear-gradient(var(--line-soft) 1px, transparent 1px), linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-position: center top; background-size: 48px 48px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 80%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 80%, transparent);
}
.magic-animated-grid-square {
  position: absolute; top: var(--grid-square-top, 50%); left: var(--grid-square-left, 50%);
  width: 48px; height: 48px; border: 1px solid rgba(30, 91, 255, .42);
  background: linear-gradient(135deg, rgba(63, 169, 245, .74), rgba(30, 91, 255, .48));
  box-shadow: inset 0 0 18px rgba(207, 230, 255, .25), 0 0 22px rgba(30, 91, 255, .15);
  opacity: 0; transform: translate3d(-50%, -50%, 0) scale(.82);
  animation: magic-grid-cell 4s ease-in-out infinite; animation-delay: var(--grid-square-delay, 0s);
  will-change: opacity, transform;
}
@keyframes magic-grid-cell {
  0%, 12%, 100% { opacity: 0; transform: translate3d(-50%, -50%, 0) scale(.82); }
  32%, 58% { opacity: var(--animated-grid-max-opacity, .14); transform: translate3d(-50%, -50%, 0) scale(1); }
  78% { opacity: 0; transform: translate3d(-50%, -50%, 0) scale(1.04); }
}

.magic-ripple { position: absolute; z-index: 0; inset: 0; overflow: visible; pointer-events: none; }
.magic-ripple-ring {
  position: absolute; top: 50%; left: 50%; width: 148px; height: 148px;
  border: 1.5px solid rgba(63, 169, 245, .45); border-radius: 999px;
  box-shadow: 0 0 22px rgba(30, 91, 255, .12);
  opacity: 0; transform: translate3d(-50%, -50%, 0) scale(.86);
  animation: magic-ripple-wave 5.46s cubic-bezier(.22, .61, .36, 1) infinite; animation-delay: var(--ripple-delay, 0s);
  will-change: transform, opacity;
}
@keyframes magic-ripple-wave {
  0% { opacity: 0; transform: translate3d(-50%, -50%, 0) scale(.86); }
  12% { opacity: .36; }
  100% { opacity: 0; transform: translate3d(-50%, -50%, 0) scale(4.25); }
}

.scroll-cue {
  position: absolute; z-index: 3; bottom: 24px; left: 50%; display: flex; flex-direction: column; align-items: center; gap: 10px;
  transform: translateX(-50%); color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
}
.scroll-cue i { width: 1px; height: 28px; overflow: hidden; background: var(--line); }
.scroll-cue i::after { width: 1px; height: 12px; display: block; background: var(--azure); content: ""; animation: scroll-cue 1.8s ease-in-out infinite; }
@keyframes scroll-cue {
  0% { transform: translateY(-14px); opacity: 0; }
  35% { opacity: 1; }
  100% { transform: translateY(30px); opacity: 0; }
}

/* 11. Theme toggle + view transition -------------------------------------------- */
.theme-toggle {
  width: 46px; height: 46px; display: inline-grid; place-items: center; border: 0; border-radius: 999px;
  background: var(--glass-bg); color: var(--text); cursor: pointer; transition: transform 220ms ease;
}
.theme-toggle:hover { transform: rotate(-12deg); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle[data-state="dark"] .icon-sun { display: block; }
.theme-toggle[data-state="dark"] .icon-moon { display: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* 12. Reduced motion ---------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    scroll-behavior: auto !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .project-card { transform: none; }
  [data-scrub] > * { opacity: 1 !important; filter: none !important; translate: none !important; scale: 1 !important; }
  .text-animate-unit, .viewport-reveal { opacity: 1; filter: none; transform: none; transition: none; }
}
