/* ============================================================
   Syed Shamoon Ashraf — Portfolio
   Dark / slate-blue theme
   ============================================================ */

:root {
  --bg: #07080b;
  --surface: #0e1116;
  --surface-2: #141922;
  --line: rgba(255, 255, 255, 0.09);
  --text: #f1f3f7;
  --muted: #949aa6;
  --accent: #5c86c4;        /* pills, buttons */
  --accent-soft: #7fa5dd;   /* labels on dark */
  --on-accent: #0a1120;     /* text sitting on --accent */
  --deep: #16233d;

  /* secondary text tones + translucent surfaces. Everything theme-dependent
     lives in these tokens, so the light theme below only redefines them.
     The colours listed in /admin can also be overridden from there. */
  --text-2: #c6c4c9;        /* body copy */
  --text-3: #b8b6bc;        /* timeline bullets */
  --soft: #cfcdd2;          /* nav links, footer pills */
  --chip-text: #e6e9f0;
  --tag-text: #ded9d5;
  --faint: #6f6e74;
  --line-strong: rgba(255, 255, 255, 0.16);
  --line-hover: rgba(255, 255, 255, 0.3);
  --tint: rgba(255, 255, 255, 0.03);
  --tint-2: rgba(255, 255, 255, 0.06);
  --bullet: rgba(255, 255, 255, 0.45);
  --nav-bg: rgba(7, 8, 11, 0.82);
  --menu-bg: rgba(12, 14, 19, 0.97);
  --float-bg: rgba(14, 17, 22, 0.86);
  --scroll-thumb: color-mix(in srgb, var(--accent) 22%, var(--surface-2));
  --scroll-thumb-hover: color-mix(in srgb, var(--accent) 38%, var(--surface-2));
  --grain-opacity: 0.032;

  /* hero + contact cards: blue in both themes, white text on top */
  --grad-1: #4a6fa5;
  --grad-2: #3a5a8d;
  --grad-3: #2f4a78;
  --grad-4: #16233d;
  --grad: linear-gradient(155deg, var(--grad-1) 0%, var(--grad-2) 30%, var(--grad-3) 62%, var(--grad-4) 100%);
  --radius-xl: 34px;
  --radius: 22px;
  --radius-sm: 14px;

  --font-display: "Poppins", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;

  --shell: 1240px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  color-scheme: dark;
}

/* ============ LIGHT THEME ============ */
:root[data-theme="light"] {
  --bg: #f4f6fa;
  --surface: #ffffff;
  --surface-2: #eef2f8;
  --line: rgba(15, 23, 42, 0.1);
  --text: #0d1420;
  --muted: #5d6675;
  --accent: #4a76b8;
  --accent-soft: #335e9e;
  --on-accent: #ffffff;

  --text-2: #3b4351;
  --text-3: #4a5261;
  --soft: #3b4351;
  --chip-text: #1f2735;
  --tag-text: #2c3442;
  --faint: #8a919c;
  --line-strong: rgba(15, 23, 42, 0.2);
  --line-hover: rgba(15, 23, 42, 0.28);
  --tint: rgba(15, 23, 42, 0.03);
  --tint-2: rgba(15, 23, 42, 0.06);
  --bullet: rgba(15, 23, 42, 0.35);
  --nav-bg: rgba(244, 246, 250, 0.86);
  --menu-bg: rgba(255, 255, 255, 0.98);
  --float-bg: rgba(255, 255, 255, 0.9);
  --scroll-thumb: color-mix(in srgb, var(--accent) 22%, #c9ced6);
  --scroll-thumb-hover: color-mix(in srgb, var(--accent) 38%, #b3bac5);
  --grain-opacity: 0.02;

  color-scheme: light;
}

/* Text/colour edits from /admin load just after first paint; hold the page
   (and its entrance animations) until they land. The head script lifts this
   after 1.5s no matter what. */
html.cms-pending .nav,
html.cms-pending main,
html.cms-pending .footer { visibility: hidden; }
html.cms-pending * { animation-play-state: paused !important; }

/* ============ SELF-COLLAPSING CONTENT ============
   Clearing a text in /admin hides it, plus the pill/button wrapped around
   it; a list with every item removed disappears; grids reflow. (The editor
   preview, html.cms-edit, keeps empty texts visible so they can be refilled.) */
html:not(.cms-edit) [data-k]:empty { display: none; }
html:not(.cms-edit) :is(.btn, .project-link, .social, .hero-meta):has(> [data-k]:empty) { display: none; }
html:not(.cms-edit) .project-top-right:not(:has(> [data-k]:not(:empty))) { display: none; }
[data-list]:empty { display: none; }

/* a short cross-fade while the theme toggle switches palettes */
html.theme-anim,
html.theme-anim *,
html.theme-anim *::before,
html.theme-anim *::after {
  transition: background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease, fill 0.35s ease !important;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* `clip` (not `hidden`) — `overflow: hidden` here turns <body> into a scroll
     container, which stops position: sticky on the nav from working */
  overflow-x: clip;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; margin: 0; letter-spacing: -0.03em; line-height: 1.02; }
p { margin: 0 0 1em; }

.shell { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 24px; }

/* ambient glow behind the page */
.page-glow {
  position: fixed;
  inset: -20% -10% auto -10%;
  height: 70vh;
  background:
    radial-gradient(52% 60% at 50% 0%, color-mix(in srgb, var(--grad-1) 28%, transparent), transparent 70%),
    radial-gradient(40% 50% at 82% 10%, color-mix(in srgb, var(--grad-4) 35%, transparent), transparent 70%);
  filter: blur(10px);
  pointer-events: none;
  z-index: 0;
}

main, .footer { position: relative; z-index: 1; }

/* ============ BUTTONS ============ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px 12px 22px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.35s var(--ease), background 0.3s, color 0.3s, border-color 0.3s;
}
.btn:hover { transform: translateY(-2px); }

.btn-icon {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.16);
  transition: transform 0.4s var(--ease);
}
.btn-icon svg { width: 15px; height: 15px; }
.btn:hover .btn-icon { transform: rotate(45deg); }

.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 86%, #fff); }

.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line);
  padding: 12px 22px;
}
.btn-ghost:hover { border-color: var(--line-hover); background: var(--tint); }

.btn-dark { background: #0d0c0c; color: #fff; }
.btn-dark .btn-icon { background: rgba(255, 255, 255, 0.12); }

.btn-outline {
  background: rgba(0, 0, 0, 0.12);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.45);
  padding: 12px 22px;
}
.btn-outline:hover { background: rgba(0, 0, 0, 0.28); }

/* ============ NAV ============ */
.nav {
  position: sticky;
  top: 0;
  /* must sit above <main>, which is later in the DOM at the same stacking level */
  z-index: 100;
  padding: 18px 0;
  margin-bottom: 0;
  /* padding and margin MUST share duration + easing: see .nav.scrolled */
  transition: padding 0.4s var(--ease), margin-bottom 0.4s var(--ease), background 0.4s, border-color 0.4s;
  border-bottom: 1px solid transparent;
}
/* The bar shrinks by 16px when scrolled, and gives the same 16px back as
   margin, so the page below never moves. If it did, the browser's scroll
   anchoring would shift the scroll position back across the threshold and
   the nav would flip between states in a loop (the flicker). */
.nav.scrolled {
  padding: 10px 0;
  margin-bottom: 16px;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; }

.brand { display: inline-flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 32px; height: 32px;
  border-radius: 10px;
  background: var(--grad);
  color: #14100e;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
}
.brand-text { font-family: var(--font-display); font-weight: 600; font-size: 17.5px; letter-spacing: -0.02em; }

.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-links a {
  position: relative;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 14.5px;
  color: var(--soft);
  transition: color 0.25s, background 0.25s;
}
.nav-links a:hover { color: var(--text); background: var(--tint-2); }

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

.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  border-radius: 12px;
  background: var(--tint-2);
  border: 1px solid var(--line);
  cursor: pointer;
  padding: 0;
}

/* ---- theme toggle ---- */
.theme-toggle {
  width: 42px; height: 42px;
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 12px;
  color: var(--text);
  background: var(--tint-2);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: background 0.25s, border-color 0.25s, transform 0.35s var(--ease);
}
.theme-toggle:hover { border-color: var(--line-hover); transform: translateY(-2px); }
.theme-toggle svg { width: 19px; height: 19px; grid-area: 1 / 1; transition: transform 0.5s var(--ease), opacity 0.3s; }
/* shows the mode you would switch TO: a sun while dark, a moon while light */
.theme-toggle .ico-moon { opacity: 0; transform: rotate(-60deg) scale(0.6); }
:root[data-theme="light"] .theme-toggle .ico-sun { opacity: 0; transform: rotate(60deg) scale(0.6); }
:root[data-theme="light"] .theme-toggle .ico-moon { opacity: 1; transform: none; }
.nav-toggle span {
  display: block;
  width: 18px; height: 2px;
  margin: 3px auto;
  background: var(--text);
  border-radius: 2px;
  transition: transform 0.3s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(2.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child { transform: translateY(-2.5px) rotate(-45deg); }

/* ============ HERO ============ */
.hero { padding: 14px 24px 0; }

.hero-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--grad);
  min-height: 520px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  isolation: isolate;
  box-shadow: 0 40px 90px -46px rgba(0, 0, 0, 0.9);
}

/* light from the top-left, deep black shadow massing through the right side —
   this is what replaced the portrait in the hero */
.hero-tint {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(70% 60% at 14% 6%, color-mix(in srgb, color-mix(in srgb, var(--accent-soft) 45%, #fff) 28%, transparent), transparent 64%),
    radial-gradient(52% 66% at 64% 88%, rgba(0, 0, 0, 0.55), transparent 72%),
    radial-gradient(95% 100% at 108% 100%, rgba(0, 0, 0, 0.88), transparent 66%),
    radial-gradient(58% 72% at 99% 4%, rgba(0, 0, 0, 0.5), transparent 74%),
    linear-gradient(160deg, transparent 42%, rgba(0, 0, 0, 0.3) 100%);
  z-index: 0;
}

.hero-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  grid-template-rows: auto 1fr;
  gap: 40px;
  padding: 52px 46px 34px;
}

.eyebrow {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  margin: 0 0 6px;
}

/* headline bottom-left, supporting block top-right — diagonal composition */
.hero-copy { grid-column: 1; grid-row: 2; align-self: end; }
.hero-side { grid-column: 2; grid-row: 1; align-self: start; }

/* three words now, so the ceiling is lower than the old two-line headline —
   otherwise "Graduate" outgrows the left column */
.hero-title {
  font-size: clamp(44px, 7.4vw, 98px);
  line-height: 0.92;
  letter-spacing: -0.045em;
  color: #fff;
  text-shadow: 0 18px 50px rgba(0, 0, 0, 0.4);
}
.hero-title span { display: block; animation: riseUp 1s var(--ease) both; }
.hero-title span:nth-child(2) { animation-delay: 0.12s; }
.hero-title span:nth-child(3) { animation-delay: 0.24s; }
@keyframes riseUp {
  from { opacity: 0; transform: translateY(28px); }
  to { opacity: 1; transform: none; }
}

.hero-side { max-width: 390px; margin-left: auto; }
.hero-side-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(19px, 1.7vw, 24px);
  line-height: 1.24;
  letter-spacing: -0.025em;
  color: #fff;
  margin-bottom: 12px;
}
.hero-side-text { font-size: 14.8px; color: rgba(255, 255, 255, 0.82); margin-bottom: 14px; }
.hero-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.9);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.22);
  padding: 7px 14px;
  border-radius: 999px;
}
.dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #7dff9b;
  box-shadow: 0 0 0 4px rgba(125, 255, 155, 0.2);
}

.hero-services {
  position: relative;
  z-index: 2;
  display: grid;
  /* auto-fit so adding/removing services in /admin reflows the row */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  padding: 22px 46px 28px;
  gap: 20px;
}
.hero-services li { display: flex; flex-direction: column; gap: 6px; }
.hero-services .num {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
}
.hero-services .num::before { content: "— "; }
.hero-services .lbl {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 15px;
  color: #fff;
  letter-spacing: -0.02em;
}

/* tech strip — every chip stays visible: label above, chips wrap below.
   (No marquee: a scrolling track always leaves items clipped off-screen.) */
.strip {
  margin-top: 16px;
  position: relative;
  z-index: 3;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 26px 24px;
}
.strip-label {
  margin: 0 0 15px;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.strip-set { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: -0.01em;
  color: var(--chip-text);
  border: 1px solid var(--line);
  background: var(--tint);
  padding: 9px 18px;
  border-radius: 999px;
  white-space: nowrap;
}

/* ============ SECTION PRIMITIVES ============ */
.section { padding: 110px 24px 0; }

.kicker {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-soft);
  margin: 0 0 18px;
}

.display {
  font-size: clamp(34px, 5.2vw, 62px);
  line-height: 1.02;
  letter-spacing: -0.04em;
}

.section-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 30px;
  align-items: end;
  padding-bottom: 44px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 44px;
}
.section-note { max-width: 320px; color: var(--muted); font-size: 15px; margin: 0; }

/* ============ ABOUT ============ */
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: start; }
.about-right p { color: var(--text-2); font-size: 16.5px; }
.about-right strong { color: var(--text); font-weight: 600; }
.about-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

/* ============ PROJECTS ============ */
/* 6 tracks so cards can span cleanly: the two biggest builds take a full row
   each, and the remaining four sit two-up — 3 + 3 fills the row exactly, so
   there's never an orphan half-card at the end */
.projects { display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px; }
.project { grid-column: span 3; }
.project-featured { grid-column: span 6; }
.project.project-full { grid-column: 1 / -1; }

.project {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 26px 26px;
  transition: transform 0.45s var(--ease), border-color 0.4s, background 0.4s;
}
.project::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto;
  height: 2px;
  background: var(--grad);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--ease);
}
.project:hover { transform: translateY(-6px); border-color: var(--line-strong); background: var(--surface-2); }
.project:hover::before { transform: scaleX(1); }

.project-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 22px; }
.project-num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: var(--accent-soft);
}
.project-date { font-size: 12.5px; color: var(--muted); }

.project h3 { font-size: 23px; letter-spacing: -0.03em; margin-bottom: 12px; }
.project-lede { color: var(--text-2); font-size: 15px; }
.project-points { display: grid; gap: 9px; margin: 16px 0 20px; }
.project-points li {
  position: relative;
  padding-left: 18px;
  font-size: 14.4px;
  color: var(--muted);
}
.project-points li::before {
  content: "";
  position: absolute;
  left: 0; top: 9px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.85;
}

.tags { display: flex; flex-wrap: wrap; gap: 8px; }
.tags span {
  font-size: 12.4px;
  font-weight: 500;
  color: var(--tag-text);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 12px;
  background: var(--tint);
}

/* --- featured project (final year project) --- */
.project-top-right { display: flex; align-items: center; gap: 12px; }
.project-flag {
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  padding: 5px 12px;
}
.project-featured { padding: 32px 30px 30px; }
.project-featured::before { transform: scaleX(1); }
.project-featured h3 { font-size: 30px; }
.project-featured .project-lede { max-width: 620px; font-size: 15.8px; }
.project-featured .project-points { grid-template-columns: 1fr 1fr; gap: 9px 30px; }

.project-link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--chip-text);
  border: 1px solid var(--line);
  background: var(--tint);
  border-radius: 999px;
  padding: 9px 18px 9px 15px;
  transition: color 0.25s, background 0.25s, border-color 0.25s, transform 0.35s var(--ease);
}
.project-link svg { width: 17px; height: 17px; flex: none; }
.project-link:hover {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-2px);
}

/* ============ TIMELINE ============ */
.timeline { display: grid; gap: 0; }
.tl-item {
  display: grid;
  grid-template-columns: 210px 1fr;
  gap: 30px;
  padding: 30px 0;
  border-top: 1px solid var(--line);
  transition: background 0.4s;
}
.tl-item:last-child { border-bottom: 1px solid var(--line); }
/* the section heading already draws the line above the first entry */
.section-head + .timeline { margin-top: -30px; }
.timeline > .tl-item:first-child { border-top-color: transparent; }
.timeline > .tl-item:first-child::after { display: none; }
.tl-item:hover { background: var(--tint); }

.tl-when {
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--muted);
  padding-top: 4px;
}
.tl-body h3 { font-size: 21px; margin-bottom: 4px; }
.tl-org { color: var(--accent-soft); font-size: 14.5px; font-weight: 500; margin-bottom: 12px; }
.tl-body ul { display: grid; gap: 8px; max-width: 760px; }
.tl-body li {
  position: relative;
  padding-left: 18px;
  color: var(--text-3);
  font-size: 15px;
}
.tl-body li::before {
  content: "";
  position: absolute;
  left: 0; top: 10px;
  width: 6px; height: 1px;
  background: var(--bullet);
}

/* ============ SKILLS + CERTS ============ */
/* flex-wrap, not a fixed grid: groups can be added or removed in /admin, and
   each row's columns stretch to fill it, so there's never an empty cell
   (which would show as a block of the divider colour) */
.skills-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.skill-col { flex: 1 1 220px; background: var(--surface); padding: 26px 24px 30px; }
.skill-col h4 {
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 16px;
}
.skill-col ul { display: grid; gap: 10px; }
.skill-col li {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 15.5px;
  letter-spacing: -0.02em;
}

/* auto-fit rather than a fixed count, so adding a certificate reflows instead
   of leaving a half-empty row */
.certs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(390px, 1fr));
  gap: 20px;
  margin-top: 20px;
}
.cert {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 24px;
  transition: border-color 0.35s, transform 0.4s var(--ease);
}
.cert:hover { border-color: var(--line-strong); transform: translateY(-4px); }
.cert h4 { font-size: 18px; margin-bottom: 6px; }
.cert-org { color: var(--accent-soft); font-size: 14px; font-weight: 500; margin-bottom: 10px; }
.cert p:last-child { color: var(--muted); font-size: 14.5px; margin: 0; }

/* ============ CONTACT ============ */
.contact { padding: 120px 24px 0; }
.contact-card {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--radius-xl);
  background: var(--grad);
  padding: 66px 48px 60px;
  text-align: center;
  box-shadow: 0 40px 90px -46px rgba(0, 0, 0, 0.9);
}
.contact-tint {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(62% 72% at 14% 8%, color-mix(in srgb, color-mix(in srgb, var(--accent-soft) 45%, #fff) 26%, transparent), transparent 66%),
    radial-gradient(70% 80% at 96% 96%, rgba(0, 0, 0, 0.62), transparent 68%);
}
.contact-card .eyebrow { text-align: center; }
.contact-title {
  font-size: clamp(38px, 6.4vw, 78px);
  line-height: 0.96;
  letter-spacing: -0.045em;
  color: #fff;
  margin-bottom: 20px;
}
.contact-text {
  max-width: 470px;
  margin: 0 auto 30px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 16px;
}
.contact-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; }

/* --- contact form (posts to /api/contact → Resend) --- */
.contact-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  max-width: 660px;
  margin: 0 auto;
  text-align: left;
}
.field { display: grid; gap: 7px; }
.field-wide { grid-column: 1 / -1; }

.field label {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.9);
}
.field label .opt { font-weight: 500; color: rgba(255, 255, 255, 0.55); }

.field input,
.field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  color: #fff;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-sm);
  padding: 12px 15px;
  transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
}
.field textarea { resize: vertical; min-height: 130px; }
.field input::placeholder,
.field textarea::placeholder { color: rgba(255, 255, 255, 0.45); }
.field input:hover,
.field textarea:hover { border-color: rgba(255, 255, 255, 0.42); }
.field input:focus,
.field textarea:focus {
  outline: none;
  background: rgba(0, 0, 0, 0.34);
  border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.14);
}
/* only flag a bad value once the field has actually been filled in */
.field input:not(:placeholder-shown):invalid { border-color: #ff9d9d; }

/* off-screen rather than display:none — bots skip hidden inputs */
.cf-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form-foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px 18px;
  margin-top: 2px;
}
#cfSubmit:disabled { opacity: 0.65; cursor: progress; transform: none; }

.form-status { margin: 0; font-size: 14px; line-height: 1.5; color: rgba(255, 255, 255, 0.85); }
.form-status:empty { display: none; }
.form-status.is-ok { color: #a9f5bd; }
.form-status.is-err { color: #ffbcbc; }

/* ============ FOOTER ============ */
.footer { padding: 70px 24px 40px; }
.footer-inner {
  border-top: 1px solid var(--line);
  padding-top: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 18px;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 10px; }
.social {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  font-weight: 500;
  color: var(--soft);
  border: 1px solid var(--line);
  background: var(--tint);
  border-radius: 999px;
  padding: 9px 16px 9px 13px;
  transition: color 0.25s, border-color 0.25s, background 0.25s, transform 0.35s var(--ease);
}
.social svg { width: 17px; height: 17px; flex: none; }
.social:hover {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-2px);
}
.footer-note { margin: 0; font-size: 13.5px; color: var(--faint); }

/* ============ REVEAL ANIMATION ============ */
/* only hidden when script.js is running (html.js), so a JS failure can never
   leave a section blank */
.reveal { transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.js .reveal:not(.in) { opacity: 0; transform: translateY(22px); }

/* ============ RESPONSIVE ============ */
@media (max-width: 1080px) {
  .hero-card { min-height: 520px; }
  .hero-inner {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    gap: 30px;
    padding: 44px 32px 30px;
  }
  .hero-copy { grid-column: 1; grid-row: 1; }
  .hero-side { grid-column: 1; grid-row: 2; margin-left: 0; max-width: 560px; }
  .hero-services { padding: 20px 32px 26px; row-gap: 18px; }
  .about-grid { grid-template-columns: 1fr; gap: 34px; }
  .project-featured .project-points { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .nav-links {
    position: absolute;
    top: calc(100% + 8px);
    left: 24px; right: 24px;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    background: var(--menu-bg);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 10px;
    display: none;
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 12px 14px; font-size: 15.5px; }
  .nav-toggle { display: block; }
  .nav-actions .btn-primary { display: none; }

  .hero-card { min-height: 480px; }
  .strip { padding: 20px 20px 22px; }
  .section-head { grid-template-columns: 1fr; align-items: start; }
  .section-note { max-width: 100%; }
  .projects, .certs { grid-template-columns: 1fr; }
  /* spans have to be reset, or a card wider than the single track would
     spill into implicit columns */
  .project, .project-featured { grid-column: 1 / -1; }
  .project-featured { padding: 28px 26px 26px; }
  .project-featured h3 { font-size: 25px; }
  .tl-item { grid-template-columns: 1fr; gap: 10px; }
  .tl-when { padding-top: 0; }
  .contact-card { padding: 52px 26px 48px; }
  .contact-form { grid-template-columns: 1fr; }
  .project-top { flex-wrap: wrap; }
}

/* Tablets. The 860px rules collapse everything to one column, which is right
   for phones but leaves a 768px iPad showing single stretched cards with a
   lot of dead space. From 700px up there is room for two abreast. */
@media (min-width: 700px) and (max-width: 860px) {
  .projects { grid-template-columns: repeat(2, 1fr); }
  .project { grid-column: auto; }
  .project-featured, .project.project-full { grid-column: 1 / -1; }
  .certs { grid-template-columns: repeat(2, 1fr); }
  .contact-form { grid-template-columns: 1fr 1fr; }
  .tl-item { grid-template-columns: 170px 1fr; gap: 24px; }
  .tl-when { padding-top: 4px; }
}

@media (max-width: 520px) {
  .section { padding-top: 84px; }
  .footer-inner { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   MOTION & POLISH
   All of it rides on transform/opacity so it composites on the GPU
   rather than forcing layout. The reduced-motion block at the very
   bottom of this file switches the whole layer off.
   ============================================================ */

::selection { background: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--text); }

/* keyboard users get a visible ring; mouse users don't */
:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 3px; border-radius: 8px; }

html { scrollbar-color: var(--scroll-thumb) var(--bg); scrollbar-width: thin; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 99px; border: 3px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }

/* fine film grain — stops the large flat darks from banding */
.grain {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: var(--grain-opacity);
  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='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* ---- scroll progress ---- */
.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 200;
  pointer-events: none;
}
.scroll-progress span {
  display: block;
  height: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--grad-1), var(--accent-soft) 55%, color-mix(in srgb, var(--accent-soft) 35%, #fff));
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent-soft) 55%, transparent);
  transition: transform 0.12s linear;
}

/* ---- nav: current section ---- */
.nav-links a::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 1px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-soft);
  opacity: 0;
  transform: translate(-50%, 6px) scale(0.4);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.nav-links a.active { color: var(--text); background: var(--tint-2); }
.nav-links a.active::after { opacity: 1; transform: translate(-50%, 0) scale(1); }

/* ---- hero entrance, continuing the headline's cascade ---- */
.hero .eyebrow { animation: riseUp 0.9s var(--ease) both; }
.hero-side-title { animation: riseUp 0.9s var(--ease) 0.3s both; }
.hero-side-text { animation: riseUp 0.9s var(--ease) 0.38s both; }
.hero-meta { animation: riseUp 0.9s var(--ease) 0.46s both; }
.hero-services li { animation: riseUp 0.8s var(--ease) both; }
.hero-services li:nth-child(1) { animation-delay: 0.54s; }
.hero-services li:nth-child(2) { animation-delay: 0.62s; }
.hero-services li:nth-child(3) { animation-delay: 0.7s; }
.hero-services li:nth-child(4) { animation-delay: 0.78s; }

/* the "open to opportunities" dot actually breathes now */
.dot { animation: pulse 2.6s ease-in-out infinite; }
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(125, 255, 155, 0.18); }
  50% { box-shadow: 0 0 0 9px rgba(125, 255, 155, 0.03); }
}

/* ---- ambient drift of the light overlay (the base gradient is left
   alone: scaling it crops out the dark end that gives the card depth) ---- */
@keyframes floatLight {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50% { transform: translate3d(2.5%, 1.8%, 0); }
}

/* ---- pointer-tracked light on the big cards ---- */
.hero-card { --hx: 22%; --hy: 10%; }
.contact-card { --hx: 50%; --hy: 0%; }
.hero-card::after, .contact-card::after {
  content: "";
  position: absolute;
  inset: -8%;
  pointer-events: none;
  background: radial-gradient(38% 46% at var(--hx) var(--hy), color-mix(in srgb, color-mix(in srgb, var(--accent-soft) 30%, #fff) 13%, transparent), transparent 72%);
  animation: floatLight 19s ease-in-out infinite;
}
.hero-card::after { z-index: 1; }
.contact-card::after { z-index: 0; }
/* keep the card's own content above that wash */
.contact-card > * { position: relative; z-index: 1; }

/* ---- cursor spotlight on project + certificate cards ---- */
.project, .cert { --mx: 50%; --my: -30%; }
.cert { position: relative; overflow: hidden; }
.project::after, .cert::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  background: radial-gradient(330px circle at var(--mx) var(--my), color-mix(in srgb, var(--accent-soft) 15%, transparent), transparent 62%);
  transition: opacity 0.4s var(--ease);
}
.project:hover::after, .cert:hover::after { opacity: 1; }
.project > *, .cert > * { position: relative; z-index: 1; }
.project::before { z-index: 2; }

/* ---- staggered reveals ---- */
.reveal { transition-delay: var(--d, 0ms); }
.stagger-item {
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js .reveal:not(.in) .stagger-item { opacity: 0; transform: translateY(14px); }

/* ---- an accent line draws across each timeline row as it arrives ---- */
.tl-item { position: relative; }
.tl-item::after {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  height: 1px;
  width: 100%;
  background: linear-gradient(90deg, var(--accent), transparent 68%);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.9s var(--ease) 0.1s;
}
.tl-item.in::after { transform: scaleX(1); }
.tl-when { transition: color 0.3s; }
.tl-item:hover .tl-when { color: var(--accent-soft); }

/* same idea under each section heading (silently skipped where :has isn't supported) */
.section-head { position: relative; }
.section-head::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 1px;
  width: 100%;
  background: linear-gradient(90deg, var(--accent-soft), transparent 55%);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 1.1s var(--ease) 0.15s;
}
.section-head:has(.display.in)::after { transform: scaleX(1); }

/* ---- small interactive details ---- */
.chip { transition: transform 0.3s var(--ease), border-color 0.3s, background 0.3s, color 0.3s; }
.chip:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent-soft) 50%, transparent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--text);
}
.tags span { transition: border-color 0.3s, color 0.3s, background 0.3s; }
.tags span:hover { border-color: color-mix(in srgb, var(--accent-soft) 45%, transparent); color: var(--text); background: color-mix(in srgb, var(--accent) 12%, transparent); }

.skill-col { transition: background 0.4s; }
.skill-col:hover { background: var(--surface-2); }
.skill-col li { transition: color 0.25s, transform 0.3s var(--ease); }
.skill-col li:hover { color: var(--accent-soft); transform: translateX(5px); }

/* light sweeps across the primary button on hover */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: "";
  position: absolute;
  top: 0;
  left: -120%;
  width: 55%;
  height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: skewX(-18deg);
  transition: left 0.75s var(--ease);
}
.btn-primary:hover::after { left: 140%; }

.project-link svg, .social svg { transition: transform 0.4s var(--ease); }
.project-link:hover svg, .social:hover svg { transform: rotate(-8deg) scale(1.12); }

/* ---- back to top ---- */
.to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 120;
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--text);
  background: var(--float-bg);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  cursor: pointer;
  opacity: 0;
  transform: translateY(14px) scale(0.9);
  pointer-events: none;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), background 0.3s, border-color 0.3s, color 0.3s;
}
.to-top.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); transform: translateY(-3px); }
.to-top svg { width: 18px; height: 18px; }

@media (max-width: 520px) {
  .to-top { right: 16px; bottom: 16px; width: 42px; height: 42px; }
}

/* ---- technology logos ----
   Chips become inline-flex so a logo can sit beside the label; chips for
   technologies with no published logo (Dynamics 365, X++, Power Platform,
   REST APIs) simply keep their label and still line up. */
.tags span { display: inline-flex; align-items: center; gap: 7px; }
.tech-ico { width: 15px; height: 15px; flex: none; }

/* simple-icons ship as one currentColor path, so they take a brand colour here */
.ico-stripe { color: #8b85ff; }
.ico-whatsapp { color: #25d366; }
.ico-gmail { color: #ea4335; }
.ico-gemini { color: #8e9bff; }
.ico-ngrok, .ico-google { color: var(--text); }


@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .js .reveal:not(.in) { opacity: 1; transform: none; }
  .js .reveal:not(.in) .stagger-item { opacity: 1; transform: none; }
  .tl-item::after, .section-head::after { transform: scaleX(1); }
  .grain { display: none; }
  html { scroll-behavior: auto; }
}
