/* =========================================================
   Aswin Paudel — Portfolio
   Royal ink & gold theme · Merriweather Light
   ========================================================= */

:root {
  /* ---- theme palette (Royal Ink & Gold). Other themes override these below. ---- */
  --ink:        #0c0a08;                 /* page background */
  --ink-2:      #13100c;                 /* alternate section */
  --ink-3:      #1b1611;                 /* panels & cards */
  --ivory:      #efe6d2;                 /* body text */
  --soft:       #d9cfbb;                 /* secondary headings */
  --muted:      #a99d87;                 /* quiet text */
  --gold:       #c8a55a;                 /* accent: labels, rules, icons */
  --gold-light: #e6cf98;                 /* accent: emphasis */
  --gold-deep:  #9a7a3a;                 /* accent: subdued */
  --gold-grad:  linear-gradient(135deg, #9a7a3a 0%, #e6cf98 45%, #c8a55a 60%, #8a6a2e 100%);
  --on-accent:  #0c0a08;                 /* text on the accent gradient */
  --grad-text:  var(--gold-grad);        /* gilded headings & numerals */
  --accent-rgb: 200, 165, 90;            /* hairlines, glows, tints */
  --glow-rgb:   230, 207, 152;           /* rim light, sheens */
  --bg-rgb:     12, 10, 8;
  --text-rgb:   239, 230, 210;
  --shadow-rgb: 0, 0, 0;
  --shadow-k:   1;                       /* shadow strength (lighter on light themes) */
  --medal:      #efe6d2;                 /* disc behind timeline logos */

  /* the letter & envelope in Correspondence */
  --paper:        #efe5cf;
  --paper-ink:    #2a2118;
  --paper-ink-rgb: 42, 33, 24;
  --paper-soft:   #3b2f22;
  --paper-muted:  #8a7658;
  --foil:         #6e501c;
  --foil-rgb:     154, 122, 58;
  --foil-grad:    linear-gradient(135deg, #6e501c, #b8913f 45%, #7a5a22 70%, #5c4216);
  --btn-ink:      #1b1510;
  --btn-ink-hover:#2a2118;
  --btn-ink-text: #e6cf98;
  --env-back-1: #120e0a;  --env-back-2: #1c1610;
  --env-front-1:#231b13;  --env-front-2:#16110c;
  --env-flap-1: #2c2218;  --env-flap-2: #1a140e;

  --line:       rgba(var(--accent-rgb), .24);
  --line-soft:  rgba(var(--accent-rgb), .12);

  --serif: "Merriweather", Georgia, "Times New Roman", serif;
  --maxw: 1180px;
  --gutter: clamp(16px, 5vw, 48px);
  --ease: cubic-bezier(.2, .7, .2, 1);
  color-scheme: dark;
}

/* ---- Onyx Platinum ---- */
:root[data-theme="onyx-platinum"] {
  --ink: #111111; --ink-2: #171717; --ink-3: #2a2a2a;
  --ivory: #ffffff; --soft: #d4d4d4; --muted: #a3a3a3;
  --gold: #e5e4e2; --gold-light: #ffffff; --gold-deep: #9c9b99;
  --gold-grad: linear-gradient(135deg, #8e8d8b 0%, #f7f7f5 45%, #d6d5d2 60%, #7d7c7a 100%);
  --on-accent: #111111;
  --accent-rgb: 229, 228, 226; --glow-rgb: 245, 245, 243;
  --bg-rgb: 17, 17, 17; --text-rgb: 255, 255, 255;
  --medal: #f2f2f0;
  --paper: #f3f3f1; --paper-ink: #1c1c1c; --paper-ink-rgb: 28, 28, 28;
  --paper-soft: #333333; --paper-muted: #6f6f6f;
  --foil: #4d4d4b; --foil-rgb: 120, 120, 118;
  --foil-grad: linear-gradient(135deg, #3f3f3d, #9d9c9a 45%, #5c5b59 70%, #333331);
  --btn-ink: #1c1c1c; --btn-ink-hover: #2e2e2e; --btn-ink-text: #e5e4e2;
  --env-back-1: #141414; --env-back-2: #1d1d1d;
  --env-front-1: #2a2a2a; --env-front-2: #191919;
  --env-flap-1: #333333; --env-flap-2: #1f1f1f;
  --line: rgba(var(--accent-rgb), .2); --line-soft: rgba(var(--accent-rgb), .1);
}

/* ---- the light themes share their structure ---- */
:root[data-theme="ivory-rose-gold"],
:root[data-theme="marble-gold"] {
  --shadow-k: .32;
  --line: rgba(var(--accent-rgb), .42); --line-soft: rgba(var(--accent-rgb), .22);
  --btn-ink-hover: #000;
  color-scheme: light;
}

/* ---- Ivory Rose Gold ---- */
:root[data-theme="ivory-rose-gold"] {
  --ink: #faf6f0; --ink-2: #f4ede5; --ink-3: #ebddd2;
  --ivory: #3a2a2d; --soft: #54403f; --muted: #76626a;
  --gold: #96505c; --gold-light: #7d3f4a; --gold-deep: #b76e79;
  --gold-grad: linear-gradient(135deg, #9b5563 0%, #e9bcc2 45%, #c98791 60%, #8d4a57 100%);
  --on-accent: #2e1d20;
  --accent-rgb: 183, 110, 121; --glow-rgb: 233, 188, 194;
  --bg-rgb: 250, 246, 240; --text-rgb: 58, 42, 45; --shadow-rgb: 80, 40, 48;
  --medal: #ffffff;
  --grad-text: linear-gradient(135deg, #7d3f4a 0%, #b0636f 45%, #8d4a57 62%, #6a3440 100%);
  --paper: #fffaf6; --paper-ink: #3a2a2d; --paper-ink-rgb: 58, 42, 45;
  --paper-soft: #54403f; --paper-muted: #8a7176;
  --foil: #8d4a57; --foil-rgb: 183, 110, 121;
  --foil-grad: linear-gradient(135deg, #7d3f4a, #c47c87 45%, #96505c 70%, #6e3540);
  --btn-ink: #3a2a2d; --btn-ink-text: #f6e3e5;
  --env-back-1: #dfcbbd; --env-back-2: #e6d5c9;
  --env-front-1: #ebddd2; --env-front-2: #e0cdc0;
  --env-flap-1: #f1e6dd; --env-flap-2: #e3d2c5;
}

/* ---- Marble & Gold ---- */
:root[data-theme="marble-gold"] {
  --ink: #ffffff; --ink-2: #f6f6f6; --ink-3: #ededed;
  --ivory: #111111; --soft: #333333; --muted: #5e5e5e;
  --gold: #b8963e; --gold-light: #735919; --gold-deep: #8c6d22;
  --gold-grad: linear-gradient(135deg, #9a7a2c 0%, #ecd9a2 45%, #c9a652 60%, #8a6c24 100%);
  --on-accent: #1a1406;
  --accent-rgb: 184, 150, 62; --glow-rgb: 236, 217, 162;
  --bg-rgb: 255, 255, 255; --text-rgb: 17, 17, 17; --shadow-rgb: 20, 20, 20;
  --medal: #ffffff;
  --grad-text: linear-gradient(135deg, #6f5418 0%, #a3822f 45%, #7d6120 62%, #5e4714 100%);
  --paper: #fdfcf9; --paper-ink: #1a1a1a; --paper-ink-rgb: 26, 26, 26;
  --paper-soft: #333333; --paper-muted: #6e6e6e;
  --foil: #7a5e1c; --foil-rgb: 184, 150, 62;
  --btn-ink: #111111; --btn-ink-text: #ecd9a2;
  --env-back-1: #dcdcdc; --env-back-2: #e4e4e4;
  --env-front-1: #ededed; --env-front-2: #e0e0e0;
  --env-flap-1: #f4f4f4; --env-flap-2: #e3e3e3;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 80px; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--ivory);
  font-family: var(--serif);
  font-weight: 300;
  font-size: 17px;
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* faint gilded glow + grain over the page */
body::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse 60% 40% at 50% 0%, rgba(var(--accent-rgb), .09), transparent 70%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .78 0 0 0 0 .65 0 0 0 0 .35 0 0 0 .05 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
:root[data-theme="onyx-platinum"] body::before,
:root[data-theme="ivory-rose-gold"] body::before { opacity: .7; }
:root[data-theme="marble-gold"] body::before {
  background: radial-gradient(ellipse 60% 40% at 50% 0%, rgba(var(--accent-rgb), .08), transparent 70%);
}

main, .footer, .nav { position: relative; z-index: 1; }

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-weight: 300; margin: 0; line-height: 1.25; }
p { margin: 0; }
ul, ol { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; }

::selection { background: var(--gold); color: var(--on-accent); }
:focus-visible { outline: 1px solid var(--gold-light); outline-offset: 4px; }

.gold-text,
.numeral,
.h-year,
.cert-abbr {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Ornament: line ◆ line ---------- */
.ornament {
  display: flex; align-items: center; gap: 12px;
  width: min(240px, 70%);
  height: 12px;
  margin: 14px auto 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M12 1 L17 6 L12 11 L7 6 Z' fill='none' stroke='%23c8a55a'/%3E%3Ccircle cx='12' cy='6' r='1.4' fill='%23e6cf98'/%3E%3Ccircle cx='2' cy='6' r='1' fill='%23c8a55a'/%3E%3Ccircle cx='22' cy='6' r='1' fill='%23c8a55a'/%3E%3C/svg%3E") center / 24px 12px no-repeat;
}
.ornament::before, .ornament::after {
  content: ""; flex: 1; height: 1px;
}
.ornament::before { background: linear-gradient(90deg, transparent, var(--gold)); margin-right: 18px; }
.ornament::after  { background: linear-gradient(90deg, var(--gold), transparent); margin-left: 18px; }

/* ---------- Buttons & links ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 15px 30px;
  font-size: .78rem;
  font-weight: 400;
  letter-spacing: .22em;
  text-transform: uppercase;
  border: 1px solid var(--gold);
  transition: background .4s var(--ease), color .4s var(--ease), box-shadow .4s var(--ease);
}
.btn-gold { background: var(--gold-grad); color: var(--on-accent); border-color: transparent; }
.btn-gold:hover { box-shadow: 0 10px 40px -10px rgba(var(--accent-rgb), .6); }
.btn-ghost { color: var(--gold-light); }
.btn-ghost:hover { background: rgba(var(--accent-rgb), .1); }

.link-arrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: .78rem; font-weight: 400;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold-light);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  transition: border-color .3s, gap .3s var(--ease);
}
.link-arrow::after { content: "→"; letter-spacing: 0; }
.link-arrow:hover { border-color: var(--gold); gap: 16px; }

/* =========================================================
   NAVIGATION
   ========================================================= */
.nav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px var(--gutter);
  transition: background .4s, padding .4s, border-color .4s,
              transform .7s var(--ease), opacity .5s var(--ease), visibility .7s;
  border-bottom: 1px solid transparent;
}
/* hidden while the opening quote is on screen (toggled by JS) */
.js .nav.nav-hidden {
  transform: translateY(-110%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.nav.scrolled {
  background: rgba(var(--bg-rgb), .86);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding-top: 12px; padding-bottom: 12px;
  border-bottom-color: var(--line-soft);
}

.monogram {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: 1px solid var(--gold);
  transform: rotate(45deg);
  transition: background .4s;
}
.monogram span {
  transform: rotate(-45deg);
  font-size: .9rem; letter-spacing: .08em;
  color: var(--gold-light);
}
.monogram:hover { background: rgba(var(--accent-rgb), .12); }

.nav-links { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 36px); }
.nav-links a {
  position: relative;
  font-size: .74rem; font-weight: 400;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--muted);
  transition: color .3s;
}
.nav-links a::after {
  content: ""; position: absolute; left: 50%; bottom: -6px;
  width: 0; height: 1px; background: var(--gold);
  transition: width .35s var(--ease), left .35s var(--ease);
}
.nav-links a:hover, .nav-links a.active { color: var(--gold-light); }
.nav-links a:hover::after, .nav-links a.active::after { width: 100%; left: 0; }
.nav-links .nav-cta {
  color: var(--gold-light);
  border: 1px solid var(--line);
  padding: 9px 18px;
}
.nav-links .nav-cta::after { display: none; }
.nav-links .nav-cta:hover { border-color: var(--gold); }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  background: none; border: 1px solid var(--line);
  cursor: pointer;
  position: relative;
}
.nav-toggle span {
  position: absolute; left: 12px; right: 12px; height: 1px;
  background: var(--gold-light);
  transition: transform .35s var(--ease), top .35s var(--ease);
}
.nav-toggle span:first-child { top: 17px; }
.nav-toggle span:last-child  { top: 25px; }
.nav-toggle[aria-expanded="true"] span:first-child { top: 21px; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child  { top: 21px; transform: rotate(-45deg); }

/* =========================================================
   HERO
   ========================================================= */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex; align-items: center;
  padding: 90px var(--gutter) 12svh;
  overflow: hidden;
  background: var(--ink);
}
/* The photo is a night stage, so the hero stays dark in every theme:
   the light themes borrow the Royal Ink palette inside it. */
:root[data-theme="ivory-rose-gold"] .hero,
:root[data-theme="marble-gold"] .hero {
  --ink: #0c0a08; --bg-rgb: 12, 10, 8;
  --ivory: #efe6d2; --text-rgb: 239, 230, 210; --muted: #a99d87;
  --gold-light: #e6cf98;
  --grad-text: linear-gradient(135deg, #9a7a3a 0%, #e6cf98 45%, #c8a55a 60%, #8a6a2e 100%);
  --line-soft: rgba(var(--accent-rgb), .16);
  color-scheme: dark;
}

/* ---------- The photograph ----------
   Shot against near-black, he stands on the right third and looks left
   into the empty dark, which is where the proverb sits. Blending with
   "lighten" lifts the photo's pure black to the page's own ink, so the
   frame dissolves; the edges are feathered as well. */
.hero-photo {
  position: absolute; inset: 0;
  margin: 0;
  pointer-events: none;
  /* scroll-linked: --p (0→1) is set on .hero by JS */
  translate: 0 calc(var(--p, 0) * 12svh);
  opacity: calc(1 - var(--p, 0) * .9);
}
.hero-photo picture { display: block; height: 100%; }
.hero-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 72% 100%;               /* keep him and the ledge in frame at any width */
  mix-blend-mode: lighten;
  filter: contrast(1.04) saturate(.95);
}
/* wider than the photo itself (16:9): cropping would take his head, so the
   whole frame is shown at full height, set against the right edge */
@media (min-aspect-ratio: 16/9) {
  .hero-photo img {
    position: absolute; right: 2vw; bottom: 0;
    width: auto; max-width: none;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 18%);
            mask-image: linear-gradient(to right, transparent, #000 18%);
  }
}
.hero-photo::after {                       /* feather all four edges into the ink */
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, var(--ink), transparent 14%, transparent 86%, var(--ink)),
    linear-gradient(to right, var(--ink), transparent 10%, transparent 92%, var(--ink));
}
/* lights up: the scene rises out of black, then settles */
.js .hero-photo img { opacity: 0; transform: scale(1.06); }
.loaded .hero-photo img { animation: lights-up 3.2s cubic-bezier(.25,.6,.2,1) .15s forwards; }
@keyframes lights-up {
  0%   { opacity: 0; transform: scale(1.06); filter: contrast(1.04) saturate(.95) brightness(.4); }
  100% { opacity: 1; transform: none;        filter: contrast(1.04) saturate(.95) brightness(1); }
}
.hero::after {                             /* the warm key light, echoed in the empty dark */
  content: "";
  position: absolute; left: 18%; top: 50%;
  width: 70vw; height: 70vw; max-width: 900px; max-height: 900px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(var(--accent-rgb), .07), transparent 62%);
  pointer-events: none;
}

.hero-frame {
  position: absolute; inset: 22px;
  z-index: 1;
  border: 1px solid var(--line-soft);
  pointer-events: none;
}
.hero-frame::before {
  content: ""; position: absolute; inset: 6px;
  border: 1px solid var(--line-soft);
}
.corner {
  position: absolute; width: 38px; height: 38px;
  border-color: var(--gold); border-style: solid; border-width: 0;
}
.corner.tl { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
.corner.tr { top: -1px; right: -1px; border-top-width: 1px; border-right-width: 1px; }
.corner.bl { bottom: -1px; left: -1px; border-bottom-width: 1px; border-left-width: 1px; }
.corner.br { bottom: -1px; right: -1px; border-bottom-width: 1px; border-right-width: 1px; }

/* ---------- Texture on the quote side ----------
   A fine art-deco lattice (double-ruled diamonds, a small diamond at each
   centre) in the theme's accent. It is a mask, so the colour follows the
   theme, and a slow band of light travels across it like a glint on
   engraved metal. It fades toward him and toward the edges.          */
.hero-texture {
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(105deg, transparent 35%, rgba(var(--glow-rgb), .55) 50%, transparent 65%) -150% 0 / 60% 100% no-repeat,
    rgba(var(--accent-rgb), .30);
  -webkit-mask-image:
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%22.75%22%3E%3Cpath%20d%3D%22M0%2036L36%200L72%2036L36%2072Z%22%2F%3E%3Cpath%20d%3D%22M5%2036L36%205L67%2036L36%2067Z%22%2F%3E%3Cpath%20d%3D%22M36%2032.5L39.5%2036L36%2039.5L32.5%2036Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"),
    radial-gradient(ellipse 58% 75% at 26% 50%, #000 0%, rgba(0,0,0,.55) 45%, transparent 100%);
  -webkit-mask-size: 72px 72px, 100% 100%;
  -webkit-mask-position: center, center;
  -webkit-mask-composite: source-in;
          mask-image:
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%22.75%22%3E%3Cpath%20d%3D%22M0%2036L36%200L72%2036L36%2072Z%22%2F%3E%3Cpath%20d%3D%22M5%2036L36%205L67%2036L36%2067Z%22%2F%3E%3Cpath%20d%3D%22M36%2032.5L39.5%2036L36%2039.5L32.5%2036Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"),
    radial-gradient(ellipse 58% 75% at 26% 50%, #000 0%, rgba(0,0,0,.55) 45%, transparent 100%);
          mask-size: 72px 72px, 100% 100%;
          mask-position: center, center;
          mask-composite: intersect;
  filter: opacity(calc(1 - var(--p, 0) * 1.1));   /* scroll fade; opacity itself is used by the intro */
  animation: lattice-glint 11s ease-in-out 3s infinite;
}
@keyframes lattice-glint {
  0%        { background-position: -150% 0, 0 0; }
  55%, 100% { background-position: 250% 0, 0 0; }
}
.js .hero-texture { opacity: 0; }
.loaded .hero-texture { animation: fade-in 2.6s var(--ease) .9s forwards, lattice-glint 11s ease-in-out 3.5s infinite; }
@media (max-width: 960px) {
  .hero-texture {
    -webkit-mask-size: 56px 56px, 100% 100%;
            mask-size: 56px 56px, 100% 100%;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%22.75%22%3E%3Cpath%20d%3D%22M0%2036L36%200L72%2036L36%2072Z%22%2F%3E%3Cpath%20d%3D%22M5%2036L36%205L67%2036L36%2067Z%22%2F%3E%3Cpath%20d%3D%22M36%2032.5L39.5%2036L36%2039.5L32.5%2036Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"), radial-gradient(ellipse 90% 34% at 40% 24%, #000 0%, rgba(0,0,0,.5) 50%, transparent 100%);
            mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2272%22%20height%3D%2272%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%22.75%22%3E%3Cpath%20d%3D%22M0%2036L36%200L72%2036L36%2072Z%22%2F%3E%3Cpath%20d%3D%22M5%2036L36%205L67%2036L36%2067Z%22%2F%3E%3Cpath%20d%3D%22M36%2032.5L39.5%2036L36%2039.5L32.5%2036Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"), radial-gradient(ellipse 90% 34% at 40% 24%, #000 0%, rgba(0,0,0,.5) 50%, transparent 100%);
  }
}

.hero-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: var(--maxw); margin: 0 auto;
}

/* ---------- The quote: the focus of the page ---------- */
.hero-quote {
  position: relative; z-index: 2;
  margin: 0;
  max-width: min(46vw, 640px);       /* stays in the dark he is looking into */
  /* scroll-linked drift: --p (0→1) is set on .hero by JS */
  opacity: calc(1 - var(--p, 0) * 1.2);
  translate: 0 calc(var(--p, 0) * -60px);
}
/* ---------- The proverb ----------
   One sentence in Playfair italic. Only "none" and "one", the contrast the
   proverb turns on, are gold foil, and a soft glint passes across them.  */
.hero-quote { --display: "Playfair Display", Georgia, "Times New Roman", serif; }
.q-mark {
  display: block;
  height: .42em;
  font-family: var(--display);
  font-size: clamp(5rem, 9vw, 8.5rem);
  line-height: .6;
  background: var(--grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.q-text {
  margin: .35em 0 0;
  font-family: var(--display);
  font-style: italic; font-weight: 400;
  font-size: clamp(1.7rem, 3.1vw, 2.9rem);
  line-height: 1.34;
  color: rgba(var(--text-rgb), .88);
  text-wrap: pretty;
}
.q-foil {
  font-style: italic; font-weight: 500;
  background:
    linear-gradient(100deg, transparent 40%, rgba(255, 248, 228, .85) 50%, transparent 60%) -150% 0 / 250% 100% no-repeat,
    var(--grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.hero-quote cite {
  display: flex; align-items: center; gap: 14px;
  margin-top: clamp(24px, 3vw, 36px);
  font-style: normal;
  font-size: .68rem; font-weight: 400;
  letter-spacing: .4em; text-transform: uppercase;
  color: var(--muted);
}
.hero-quote cite::before { content: ""; width: 40px; height: 1px; background: var(--gold); }

/* ---------- Intro sequence (runs once .loaded is on <html>) ---------- */
.js .q-mark, .js .q-text, .js .hero-quote cite { opacity: 0; }
.js .q-mark { transform: translateY(20px); }
.js .q-text { transform: translateY(16px); filter: blur(6px); }
.js .hero-quote cite { transform: translateX(-14px); }

.loaded .q-mark          { animation: rise 1.4s var(--ease) .9s forwards; }
.loaded .q-text          { animation: line-in 1.6s var(--ease) 1.3s forwards; }
.loaded .q-foil          { animation: foil-glint 6s ease-in-out 3.4s infinite; }
.loaded .hero-quote cite { animation: rise 1.1s var(--ease) 2.6s forwards; }

@keyframes line-in    { to { opacity: 1; transform: none; filter: none; } }
@keyframes foil-glint {
  0%        { background-position: -150% 0, 0 0; }
  40%, 100% { background-position: 250% 0, 0 0; }
}
@keyframes rise    { to { opacity: 1; transform: none; } }
@keyframes fade-in { to { opacity: 1; } }

/* cut-out portrait (About section): no frame, he stands in a pool of gold light */
.portrait {
  position: relative;
  margin: 0; justify-self: center; width: min(100%, 500px);
  isolation: isolate;                      /* keeps the glow behind him, not behind the section */
}
.portrait::before {                        /* the gold light behind him */
  content: ""; position: absolute; inset: 4% -14% 6%;
  background:
    radial-gradient(ellipse 46% 42% at 52% 46%, rgba(var(--glow-rgb), .30), transparent 72%),
    radial-gradient(ellipse 62% 58% at 52% 50%, rgba(var(--accent-rgb), .20), transparent 75%);
  filter: blur(6px);
  z-index: -1;
  opacity: .85;
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  pointer-events: none;
}
.portrait::after {                         /* a gilt horizon he rises from */
  content: ""; position: absolute; left: -6%; right: -6%; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold) 30%, var(--gold-light) 50%, var(--gold) 70%, transparent);
  box-shadow: 0 0 18px 1px rgba(var(--accent-rgb), .45);
}
.portrait-cut {
  transform: scaleX(-1);                   /* mirrored, so he faces into the text */
  transform-origin: 50% 100%;
  /* room above his head and beside the phone, so the hover glow is never clipped
     (left padding becomes the right side once mirrored) */
  padding: 28px 0 0 22px;
  margin-top: -28px;
  transition: transform 1.2s var(--ease);
  /* the photo ends at his hands and shoulder, so let those edges dissolve */
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 22%), linear-gradient(to left, transparent 0, #000 14%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to top, transparent 0, #000 22%), linear-gradient(to left, transparent 0, #000 14%);
          mask-composite: intersect;
}
.portrait-cut picture { display: block; }
.portrait-cut img {
  width: 100%; height: auto;
  filter: saturate(.92) contrast(1.03) drop-shadow(0 0 0 rgba(var(--glow-rgb), 0));
  transition: filter 1.2s var(--ease);
}
/* the lift and zoom move the masked box itself, so the mask travels with him
   and nothing is cropped */
.portrait:hover .portrait-cut { transform: scaleX(-1) translateY(-6px) scale(1.03); }
.portrait:hover .portrait-cut img {
  filter: saturate(.96) contrast(1.04) drop-shadow(0 0 14px rgba(var(--glow-rgb), .45));   /* gold rim light */
}
.portrait:hover::before { opacity: 1; transform: scale(1.06); }

/* =========================================================
   SECTIONS
   ========================================================= */
.section {
  position: relative;
  padding: clamp(56px, 7vw, 96px) var(--gutter);
}
.section > * { max-width: var(--maxw); margin-left: auto; margin-right: auto; }
.section-alt {
  background: linear-gradient(180deg, var(--ink-2), var(--ink) 100%);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}

.section-head { text-align: center; margin-bottom: clamp(28px, 3.6vw, 44px); }
.numeral {
  display: block;
  font-style: italic;
  font-size: 1.05rem;
  letter-spacing: .3em;
  margin-bottom: 6px;
}
.section-head h2,
.section-head .page-title {
  font-size: clamp(2.1rem, 4.6vw, 3.3rem);
  letter-spacing: .01em;
}

.sub-head {
  text-align: center;
  font-size: .78rem; font-weight: 400;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 24px;
}

/* ---------- About ---------- */
.about-grid {
  display: grid; grid-template-columns: minmax(280px, 1fr) 1.2fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.about-grid p { color: var(--soft); }

/* body paragraphs are set justified, book-style; hyphenation keeps the word spacing even.
   (Community cards are too narrow for it at any width, so they stay left-aligned.) */
.about-grid p, .about-side blockquote,
.project-desc, .contact-lede {
  text-align: justify;
  hyphens: auto; -webkit-hyphens: auto;
}
/* narrow columns justify badly (rivers of space), so phones read them left-aligned */
@media (max-width: 640px) {
  .about-grid p, .about-side blockquote,
  .project-desc, .contact-lede { text-align: left; }
}
.about-body, .about-side { display: grid; gap: 28px; }
.drop-cap { font-size: 1.12rem; line-height: 1.9; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.drop-cap .drop {
  float: left;
  font-size: 3.05em; line-height: .86;
  padding: 6px 10px 0 0;
  font-style: italic;
  color: var(--gold);
}
.about-side blockquote {
  margin: 0;
  padding: 26px 0 26px 30px;
  border-left: 1px solid var(--gold);
  font-style: italic;
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--gold-light);
}

/* ---------- Timeline ---------- */
.timeline { position: relative; max-width: 880px; }
.timeline::before {
  content: ""; position: absolute;
  left: 50px; top: 10px; bottom: 10px; width: 1px;
  background: linear-gradient(180deg, transparent, var(--gold) 12%, var(--gold) 88%, transparent);
}
.timeline li {
  position: relative;
  display: grid; grid-template-columns: 100px 1fr;
  gap: clamp(20px, 4vw, 40px);
  align-items: center;
}
.timeline li + li { margin-top: 44px; }

.tl-node {
  width: 100px; height: 100px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--ink);
  border: 1px solid var(--gold);
  box-shadow: 0 0 0 6px var(--ink), 0 0 0 7px var(--line);
  position: relative; z-index: 1;
}
.medallion {
  width: 84px; height: 84px;
  border-radius: 50%;
  object-fit: contain;
  background: var(--medal);
  padding: 8px;
}
.medallion.wide { padding: 14px 8px; }

.tl-card {
  padding: 30px 34px;
  background: linear-gradient(135deg, rgba(var(--accent-rgb), .06), rgba(var(--accent-rgb), .01));
  border: 1px solid var(--line-soft);
  transition: border-color .4s, transform .4s var(--ease);
}
.tl-card:hover { border-color: var(--line); transform: translateX(4px); }
.tl-date {
  font-size: .7rem; font-weight: 400;
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--gold);
}
.tl-card h3 { margin-top: 10px; font-size: clamp(1.25rem, 2.4vw, 1.55rem); }
.tl-org { margin-top: 8px; color: var(--muted); font-size: .95rem; }
.tl-badge {
  display: inline-block; margin-top: 16px;
  padding: 6px 14px;
  font-size: .72rem; font-style: italic;
  letter-spacing: .06em;
  color: var(--on-accent);
  background: var(--gold-grad);
}

/* ---------- Skills ---------- */
.skills {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(30px, 6vw, 80px);
  align-items: center;
}
.skill-col h3 {
  font-size: .78rem; font-weight: 400;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.skill-col:first-child { text-align: right; }
.skill-col li {
  padding: 18px 0;
  font-size: 1.2rem;
  border-bottom: 1px solid var(--line-soft);
  transition: color .3s, padding .3s var(--ease);
}
.skill-col li:hover { color: var(--gold-light); }
.skill-col:first-child li:hover { padding-right: 10px; }
.skill-col:last-child li:hover { padding-left: 10px; }
/* the portrait between the two lists: a front-facing cut-out, framed head to
   just below the folder, standing in gold backlight on a gilt horizon */
.skill-figure {
  position: relative;
  margin: 0;
  width: clamp(220px, 23vw, 310px);
  aspect-ratio: 520 / 900;                 /* head to just below the folder and hand */
  isolation: isolate;
}
.skill-figure::before {                    /* backlight, so the black suit separates from the dark */
  content: ""; position: absolute; inset: 2% -30% 8%;
  background:
    radial-gradient(ellipse 36% 28% at 50% 26%, rgba(var(--glow-rgb), .12), transparent 72%),
    radial-gradient(ellipse 52% 46% at 50% 42%, rgba(var(--accent-rgb), .08), transparent 75%);
  filter: blur(6px);
  z-index: -1;
  pointer-events: none;
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}
.skill-figure::after {                     /* gilt horizon where the photo fades out */
  content: ""; position: absolute; left: -16%; right: -16%; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold) 30%, var(--gold-light) 50%, var(--gold) 70%, transparent);
  box-shadow: 0 0 10px rgba(var(--accent-rgb), .2);
}
.skill-figure picture {
  display: block; height: 100%;
  overflow: hidden;
  /* a little room above his head and beside his arms, so the rim light isn't clipped */
  padding: 3% 3% 0;
  margin: -3% -3% 0;
  box-sizing: content-box;
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 24%);
          mask-image: linear-gradient(to top, transparent 0, #000 24%);
}
.skill-figure img {
  width: 100%; height: auto;
  /* a fine warm rim around his outline, then a soft halo */
  filter: drop-shadow(0 0 1px rgba(var(--glow-rgb), .3));
  transform-origin: 50% 30%;
  transition: transform 1.2s var(--ease), filter 1.2s var(--ease);
}
.skill-figure:hover img {
  transform: scale(1.025);
  filter: drop-shadow(0 0 1px rgba(var(--glow-rgb), .5));
}
.skill-figure:hover::before { transform: scale(1.06); }

/* ---------- Honours ---------- */
.honours { max-width: 900px; }
.honours li {
  display: grid;
  grid-template-columns: 110px 170px 1fr;
  gap: 24px;
  align-items: baseline;
  padding: 28px 8px;
  border-bottom: 1px solid var(--line-soft);
  transition: background .4s;
}
.honours li:first-child { border-top: 1px solid var(--line-soft); }
.honours li:hover { background: rgba(var(--accent-rgb), .04); }
.h-year { font-style: italic; font-size: 1.7rem; }
.h-rank {
  font-size: .72rem; font-weight: 400;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--muted);
}
.h-event { font-size: 1.2rem; }
.honours li.is-gold .h-rank { color: var(--gold-light); }
.honours li.is-gold .h-rank::before { content: "♛ "; color: var(--gold); letter-spacing: 0; }

.certs { margin-top: clamp(48px, 6vw, 72px); }
.cert-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 28px;
  max-width: 900px; margin: 0 auto;
}
.cert {
  position: relative;
  padding: 50px 36px 42px;
  text-align: center;
  border: 1px solid var(--line);
  background: radial-gradient(ellipse at top, rgba(var(--accent-rgb), .08), transparent 70%);
  transition: border-color .4s, transform .4s var(--ease);
}
.cert::before {
  content: ""; position: absolute; inset: 8px;
  border: 1px solid var(--line-soft);
  pointer-events: none;
}
.cert:hover { border-color: var(--gold); transform: translateY(-4px); }
/* the certificate itself, framed like a document on the card */
.cert-doc { margin: 0 0 30px; }
.cert-doc button {
  display: block; width: 100%;
  padding: 0; border: 0; background: none; cursor: zoom-in;
  position: relative;
}
.cert-doc button::after {
  content: ""; position: absolute; inset: 0;
  border: 1px solid var(--line);
  transition: border-color .4s;
  pointer-events: none;
}
.cert-doc img {
  display: block; width: 100%; height: auto;
  filter: saturate(.85) brightness(.9);
  box-shadow: 0 18px 40px -18px rgba(var(--shadow-rgb), calc(.8 * var(--shadow-k)));
  transition: filter .5s var(--ease);
}
.cert-doc button:hover img { filter: saturate(1) brightness(1); }
.cert-doc button:hover::after { border-color: var(--gold); }
.cert-verify { position: relative; margin-top: 24px; }
.cert-abbr { font-size: 1.9rem; letter-spacing: .12em; }
.cert h4 { margin-top: 12px; font-size: 1.05rem; color: var(--soft); }
.cert-year {
  margin-top: 18px;
  font-size: .72rem; font-weight: 400;
  letter-spacing: .3em; color: var(--gold);
}

/* ---------- Projects ----------
   Showcase rows: a framed "window" (terminal or browser) beside the
   write-up, alternating sides, in a gilded frame with corner brackets. */
.projects { display: grid; gap: clamp(32px, 4.5vw, 56px); }
.project {
  position: relative;
  display: grid; grid-template-columns: 1.08fr 1fr;
  gap: clamp(34px, 5vw, 64px);
  align-items: center;
  padding: clamp(30px, 4.5vw, 56px);
  border: 1px solid var(--line);
  background:
    radial-gradient(ellipse 60% 80% at 0% 50%, rgba(var(--accent-rgb), .10), transparent 65%),
    var(--ink-3);
  box-shadow: 0 40px 90px -50px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k)));
}
.project.is-flip { grid-template-columns: 1fr 1.08fr; }
.project.is-flip { background: radial-gradient(ellipse 60% 80% at 100% 50%, rgba(var(--accent-rgb), .10), transparent 65%), var(--ink-3); }
.project.is-flip .project-media { order: 2; }
.project::before {                       /* inner rule of the double frame */
  content: ""; position: absolute; inset: 10px;
  border: 1px solid var(--line-soft);
  pointer-events: none;
}

/* the showcase window */
.project-media { display: block; position: relative; z-index: 0; }
.project-media::before {                 /* offset gold outline behind */
  content: ""; position: absolute; inset: 18px -18px -18px 18px;
  border: 1px solid var(--line);
  z-index: -1;
  pointer-events: none;
}
.project.is-flip .project-media::before { inset: 18px 18px -18px -18px; }
.window {
  overflow: hidden;
  border: 1px solid rgba(var(--glow-rgb), .35);
  background: #0a0908;
  box-shadow: 0 30px 60px -24px rgba(var(--shadow-rgb), calc(.95 * var(--shadow-k))), 0 0 0 6px rgba(var(--accent-rgb), .06);
  transition: transform .6s var(--ease), box-shadow .6s var(--ease), border-color .6s;
}
.project:hover .window { transform: translateY(-6px); border-color: var(--gold); box-shadow: 0 40px 70px -24px rgba(var(--shadow-rgb), calc(.95 * var(--shadow-k))), 0 0 50px -12px rgba(var(--accent-rgb), .4); }
.window-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 11px 14px;
  background: linear-gradient(to bottom, #1f1a14, #16120e);
  border-bottom: 1px solid var(--line);
}
.window-bar i { width: 9px; height: 9px; border-radius: 50%; border: 1px solid var(--gold-deep); }
.window-bar i:first-child { background: var(--gold-deep); }
.window-bar span {
  margin-left: 10px;
  font-size: .68rem; letter-spacing: .12em;
  color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.window img { width: 100%; height: auto; aspect-ratio: 1200 / 750; object-fit: cover; object-position: top; }
.term {
  margin: 0; padding: 20px 22px 24px;
  font: 400 .8rem/1.75 ui-monospace, "Cascadia Mono", Consolas, Menlo, monospace;
  color: #cfc4ad;
  white-space: pre-wrap; word-break: break-word;
  background: radial-gradient(ellipse at top left, rgba(var(--accent-rgb), .07), transparent 60%);
}
.t-p  { color: rgb(var(--glow-rgb)); }
.t-h  { color: rgb(var(--glow-rgb)); }
.t-in { color: #efe6d2; }
.t-s  { color: rgba(var(--glow-rgb), .7); }
.t-ok { color: #9fc08a; }
.t-cur {
  display: inline-block; width: .6em; height: 1.1em; vertical-align: -.2em;
  background: rgb(var(--glow-rgb));
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* the write-up */
.project-body { position: relative; }
.project-kicker {
  display: flex; align-items: center; gap: 14px;
  font-size: .7rem; font-weight: 400;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
}
.project-kicker::before { content: ""; width: 40px; height: 1px; background: var(--gold); }
.project h3 {
  margin-top: 18px;
  font-size: clamp(1.7rem, 3.2vw, 2.4rem); line-height: 1.18;
  font-style: italic;
  background: var(--grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.project-desc { margin-top: 16px; color: var(--muted); }
.project-points { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line-soft); }
.project-points li {
  position: relative;
  padding-left: 22px;
  font-size: .94rem; color: var(--soft);
}
.project-points li + li { margin-top: 10px; }
.project-points li::before {
  content: ""; position: absolute; left: 2px; top: .72em;
  width: 6px; height: 6px;
  border: 1px solid var(--gold); transform: rotate(45deg);
}
.project .tags { margin: 24px 0 0; }
.project-links { margin-top: 30px; }

.tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 26px 0 30px; }
.tags li {
  padding: 5px 14px;
  font-size: .72rem; font-weight: 400;
  letter-spacing: .12em;
  color: var(--gold-light);
  border: 1px solid var(--line);
}

/* ---------- Community ----------
   Each card reads top to bottom the same way: kind · when, name, role, what. */
.community {
  display: flex; flex-wrap: wrap; justify-content: center;   /* a short last row sits centred */
  gap: 24px;
}
.community > article { flex: 0 1 calc((100% - 48px) / 3); }
.community article {
  display: flex; flex-direction: column;
  padding: 34px 30px 32px;
  border: 1px solid var(--line-soft);
  border-top: 2px solid var(--gold-deep);
  background: linear-gradient(to bottom, rgba(var(--accent-rgb), .05), transparent 60%);
  transition: border-color .4s, transform .4s var(--ease);
}
.community article:hover { border-color: var(--line); border-top-color: var(--gold); transform: translateY(-4px); }
.c-meta {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: .7rem; font-weight: 400;
  letter-spacing: .22em; text-transform: uppercase;
}
.c-kind { color: var(--gold); }
.c-when { color: var(--muted); }
.community h3 { margin-top: 22px; font-size: 1.4rem; line-height: 1.25; }
.c-role {
  margin-top: 8px;
  font-style: italic; color: var(--gold-light);
}
.c-desc {
  margin-top: 18px; padding-top: 18px;
  border-top: 1px solid var(--line-soft);
  color: var(--muted); font-size: .95rem;
}
.c-desc strong { color: var(--soft); font-weight: 400; }
.c-link { align-self: flex-start; margin-top: 24px; }

/* ---------- Gallery ---------- */
.gallery { columns: 3 300px; column-gap: 20px; }
.gallery figure {
  margin: 0 0 20px;
  break-inside: avoid;
  position: relative;
}
.gallery button {
  display: block; width: 100%;
  padding: 0; border: 0; background: none;
  cursor: zoom-in;
  overflow: hidden;
  position: relative;
}
.gallery button::after {
  content: ""; position: absolute; inset: 0;
  border: 1px solid var(--line-soft);
  box-shadow: inset 0 0 0 0 rgba(var(--accent-rgb), 0);
  transition: box-shadow .5s var(--ease), border-color .5s;
}
.gallery img {
  width: 100%; height: auto;
  filter: saturate(.85) brightness(.9);
  transition: transform 1.1s var(--ease), filter .6s;
}
.gallery button:hover img { transform: scale(1.05); filter: saturate(1) brightness(1); }
.gallery button:hover::after { border-color: var(--gold); box-shadow: inset 0 0 0 6px rgba(var(--bg-rgb), .5); }
.gallery figcaption {
  padding: 12px 2px 0;
  font-size: .68rem; font-weight: 400;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--muted);
}
/* link to the full gallery page, and that page itself (clears the fixed nav) */
.gallery-more { text-align: center; margin-top: clamp(28px, 4vw, 44px); }
.gallery-page { padding-top: calc(clamp(56px, 7vw, 96px) + 72px); min-height: 100vh; }

/* ---------- Writing ----------
   Corner brackets (also used on the project cards) and the two banners
   linking out to the articles and blog sites.                          */
.fx-corner {
  position: absolute; width: 34px; height: 34px;
  border: 0 solid var(--gold);
  pointer-events: none;
}
.fx-corner.tl { top: -1px; left: -1px; border-top-width: 2px; border-left-width: 2px; }
.fx-corner.tr { top: -1px; right: -1px; border-top-width: 2px; border-right-width: 2px; }
.fx-corner.bl { bottom: -1px; left: -1px; border-bottom-width: 2px; border-left-width: 2px; }
.fx-corner.br { bottom: -1px; right: -1px; border-bottom-width: 2px; border-right-width: 2px; }

/* banners linking out to the articles & blog sites */
.site-banner {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  gap: clamp(22px, 4vw, 48px);
  padding: clamp(26px, 3.6vw, 40px) clamp(26px, 4vw, 52px);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  background:
    linear-gradient(100deg, rgba(var(--accent-rgb), .12), transparent 55%),
    var(--ink-3);
  overflow: hidden;
  transition: border-color .5s, transform .5s var(--ease), box-shadow .5s var(--ease);
}
.site-banner::after {                          /* light sweep, as on the posts */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(var(--glow-rgb), .12) 50%, transparent 65%);
  transform: translateX(-100%);
  transition: transform 1.1s var(--ease);
  pointer-events: none;
}
.site-banner:hover { border-color: var(--gold); transform: translateY(-4px); box-shadow: 0 30px 60px -30px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k))), 0 0 40px -18px rgba(var(--accent-rgb), .4); }
.site-banner:hover::after { transform: translateX(100%); }
.sb-articles { max-width: 1000px; }
.sb-blogs { max-width: 1000px; margin-top: clamp(20px, 2.6vw, 28px); }
.sb-text { display: flex; flex-direction: column; gap: 8px; }
.sb-tag {
  display: inline-flex; align-items: center; gap: 14px;
  font-size: .7rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
}
.sb-tag::before { content: ""; width: 32px; height: 1px; background: var(--gold); }
.sb-title {
  font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 1.2;
  font-style: italic;
  background: var(--grad-text);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.sb-desc { color: var(--muted); font-size: .98rem; }
.sb-cta { display: flex; flex-shrink: 0; }
.sb-cta .btn { padding: 14px 24px; }

/* ---------- Contact ----------
   An envelope sealed in gold. JS sets the pieces from one progress value:
   the seal cracks, the flap swings open, the ivory letter rises out and
   settles in front. Without JS (or with reduced motion) it rests open.  */
.contact { text-align: center; }
.env-scene {
  position: relative;
  max-width: 720px;
  margin-top: clamp(24px, 4vw, 44px);
  padding-bottom: 31.25%;               /* half the envelope (16:10) peeks below the letter */
  transition: padding-bottom .8s var(--ease);
}
/* once the letter is out, the empty envelope falls away and its space closes up */
.env-scene.env-leaving .envelope { opacity: 0; translate: 0 40px; transition: opacity .6s var(--ease), translate .6s var(--ease); }
.env-scene.env-done { padding-bottom: 0; }
.env-scene.env-done .envelope { display: none; }

/* the letter: ivory stationery, ink text, gold-foil accents */
.env-letter {
  position: relative; z-index: 5;
  width: 88%; margin: 0 auto;
  padding: clamp(44px, 6vw, 64px) clamp(24px, 6vw, 64px) clamp(38px, 5vw, 52px);
  text-align: left;
  color: var(--paper-ink);
  background:
    radial-gradient(ellipse 80% 50% at 50% 0%, rgba(255,255,255,.55), transparent 70%),
    radial-gradient(ellipse at 100% 100%, rgba(var(--foil-rgb),.16), transparent 60%),
    var(--paper);
  box-shadow: 0 30px 70px -25px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k))), 0 2px 0 rgba(255,255,255,.4) inset;
  transform-origin: 50% 100%;
  will-change: transform, clip-path;
}
.env-letter::before {                     /* gold-foil double rule */
  content: ""; position: absolute; inset: 12px;
  border: 1px solid rgba(var(--foil-rgb),.55);
  box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px rgba(var(--foil-rgb),.3);
  pointer-events: none;
}
.paper-head {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 30px;
}
.paper-head::before, .paper-head::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, rgba(var(--foil-rgb),.7)); }
.paper-head::after { background: linear-gradient(90deg, rgba(var(--foil-rgb),.7), transparent); }
.paper-head span {
  font-size: 1.15rem; font-style: italic; letter-spacing: .08em;
  background: var(--foil-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.paper-salute { font-size: 1.25rem; font-style: italic; color: var(--foil); }
.env-letter .contact-lede {
  margin-top: 14px;
  font-size: clamp(1.02rem, 2vw, 1.18rem); line-height: 1.75;
  color: var(--paper-soft);
}
.paper-label {
  margin-top: 30px;
  font-size: .66rem; font-weight: 400;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--paper-muted);
}
.contact-email {
  display: inline-block; position: relative;
  margin-top: 6px; padding-bottom: 6px;
  font-size: clamp(1.3rem, 4vw, 2.2rem); line-height: 1.3;
  font-style: italic;
  background: var(--foil-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  word-break: break-word;
}
.contact-email::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--foil);
  transform: scaleX(.3); transform-origin: left;
  transition: transform .6s var(--ease);
}
.contact-email:hover::after { transform: scaleX(1); }
.paper-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.btn-ink { background: var(--btn-ink); color: var(--btn-ink-text); border-color: var(--btn-ink); }
.btn-ink:hover { background: var(--btn-ink-hover); box-shadow: 0 12px 30px -12px rgba(var(--shadow-rgb), calc(.8 * var(--shadow-k))); }
.btn-ink-ghost { background: transparent; color: var(--paper-ink); border-color: rgba(var(--paper-ink-rgb), .45); cursor: pointer; }
.btn-ink-ghost:hover { border-color: var(--paper-ink); background: rgba(var(--paper-ink-rgb), .06); }
.copy-note { min-height: 1.4em; margin-top: 10px; font-size: .8rem; font-style: italic; color: var(--foil); }
.paper-sign {
  margin-top: 14px;
  font-size: clamp(1.4rem, 3vw, 1.8rem); font-style: italic;
  color: var(--paper-ink);
}
.paper-sign span { display: block; margin-bottom: 4px; font-size: .95rem; color: var(--foil); }

/* the envelope */
.envelope {
  position: absolute; left: 0; right: 0; bottom: 0;
  aspect-ratio: 16 / 10;
  --drop: 0px;
  --lift: 0px;                            /* JS: how far above its resting place it is (negative = up) */
}
.env-back, .env-front, .env-flap { position: absolute; inset: 0; translate: 0 calc(var(--drop) + var(--lift)); }
.env-back {
  z-index: 1;
  background: linear-gradient(to bottom, var(--env-back-1), var(--env-back-2));
  border: 1px solid var(--line);
  box-shadow: 0 50px 90px -40px rgba(var(--shadow-rgb), calc(.95 * var(--shadow-k)));
}
.env-front {
  z-index: 3;
  clip-path: polygon(0 0, 50% 58%, 100% 0, 100% 100%, 0 100%);
  background:
    radial-gradient(ellipse 70% 60% at 50% 100%, rgba(var(--accent-rgb), .12), transparent 70%),
    linear-gradient(to bottom, var(--env-front-1), var(--env-front-2));
  border: 1px solid rgba(var(--accent-rgb), .4);
}
.env-flap {
  z-index: 1;                            /* resting state: open, behind the letter */
  bottom: auto; height: 100%;
  transform-origin: 50% 0;
  transform: perspective(1600px) rotateX(180deg);
  clip-path: polygon(0 0, 100% 0, 50% 60%);
  background: linear-gradient(to bottom, var(--env-flap-1), var(--env-flap-2));
}
.envelope svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.envelope polyline { fill: none; stroke: rgba(var(--glow-rgb), .55); stroke-width: 1; vector-effect: non-scaling-stroke; }
.env-front polyline + polyline { stroke: rgba(var(--accent-rgb), .22); }

/* the wax seal, in two halves that crack apart */
.env-seal {
  position: absolute; z-index: 6;
  left: 50%; top: 60%;
  width: clamp(58px, 11vw, 84px); aspect-ratio: 1;
  translate: -50% calc(-50% + var(--drop) + var(--lift));
  --crack: 1;                            /* resting state: already broken away */
  opacity: calc(1 - var(--crack));
  pointer-events: none;
}
.env-seal i {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--gold-grad);
  box-shadow: 0 10px 24px -6px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k))), inset 0 0 0 5px rgba(var(--shadow-rgb), calc(.12 * var(--shadow-k))), inset 0 0 0 6px rgba(255,240,200,.35);
}
.env-seal .l { clip-path: polygon(0 0, 54% 0, 44% 38%, 56% 62%, 46% 100%, 0 100%);
  transform: translate(calc(var(--crack) * -16px), calc(var(--crack) * 10px)) rotate(calc(var(--crack) * -14deg)); }
.env-seal .r { clip-path: polygon(54% 0, 100% 0, 100% 100%, 46% 100%, 56% 62%, 44% 38%);
  transform: translate(calc(var(--crack) * 16px), calc(var(--crack) * 10px)) rotate(calc(var(--crack) * 14deg)); }
.env-seal .w { opacity: calc(1 - var(--crack) * 40); }   /* whole until the first instant of the crack */
.env-seal span { font-size: clamp(1.05rem, 2.2vw, 1.5rem); font-style: italic; color: var(--on-accent); text-shadow: 0 1px 0 rgba(255,240,200,.4); }

/* profiles */
.socials-head {
  margin-top: clamp(40px, 5vw, 60px);
  font-size: .72rem; font-weight: 400;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
}
.socials {
  max-width: 860px;
  margin-top: 26px;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.socials a {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  height: 100%;
  padding: 26px 12px 22px;
  border: 1px solid var(--line-soft);
  background: linear-gradient(to bottom, rgba(var(--accent-rgb), .05), transparent);
  transition: border-color .4s, transform .4s var(--ease), background .4s, box-shadow .4s var(--ease);
}
.socials svg {
  width: 22px; height: 22px; margin-bottom: 8px;
  fill: var(--gold);
  transition: fill .4s, transform .4s var(--ease);
}
.s-name {
  font-size: .74rem; font-weight: 400;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--ivory);
}
.s-handle { font-size: .78rem; font-style: italic; color: var(--muted); word-break: break-all; }
.socials a:hover {
  border-color: var(--gold); transform: translateY(-4px);
  background: linear-gradient(to bottom, rgba(var(--accent-rgb), .12), transparent);
  box-shadow: 0 20px 40px -24px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k))), 0 0 30px -14px rgba(var(--accent-rgb), .45);
}
.socials a:hover svg { fill: var(--gold-light); transform: scale(1.1); }

/* ---------- Footer ---------- */
.footer {
  padding: 50px var(--gutter) 60px;
  text-align: center;
  border-top: 1px solid var(--line-soft);
}
.footer .ornament { margin: 0 auto 22px; }
.footer p {
  font-size: .7rem; font-weight: 400;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--muted);
}

/* ---------- Theme picker ----------
   A small gilded button in the corner, always reachable (the nav hides
   over the hero); it opens a card of swatches.                          */
.theme-dock { position: fixed; right: 18px; bottom: 18px; z-index: 60; }
.theme-btn {
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: rgba(var(--bg-rgb), .82);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 10px 30px -12px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k)));
  cursor: pointer;
  transition: transform .4s var(--ease), box-shadow .4s;
}
.theme-btn:hover { transform: rotate(45deg); box-shadow: 0 10px 30px -10px rgba(var(--accent-rgb), .5); }
.theme-btn svg { width: 20px; height: 20px; fill: none; stroke: var(--gold); stroke-width: 1.4; }
.theme-menu {
  position: absolute; right: 0; bottom: 58px;
  width: 250px;
  padding: 18px 16px 12px;
  border: 1px solid var(--line);
  background: var(--ink-3);
  box-shadow: 0 30px 60px -20px rgba(var(--shadow-rgb), calc(.9 * var(--shadow-k)));
  animation: fade .3s var(--ease);
}
.theme-menu[hidden] { display: none; }
.theme-menu::before { content: ""; position: absolute; inset: 5px; border: 1px solid var(--line-soft); pointer-events: none; }
.theme-title {
  margin: 0 0 10px 6px;
  font-size: .64rem; font-weight: 400;
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--gold);
}
.theme-opt {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 9px 8px;
  border: 0; background: none; cursor: pointer;
  text-align: left;
  font-size: .86rem; color: var(--ivory);
  transition: background .3s;
}
.theme-opt:hover { background: rgba(var(--accent-rgb), .1); }
.theme-opt[aria-checked="true"] { color: var(--gold-light); }
.theme-opt[aria-checked="true"]::after { content: "\2713"; margin-left: auto; color: var(--gold); }
.sw {
  flex: none;
  width: 26px; height: 26px; border-radius: 50%;
  background: linear-gradient(135deg, var(--sw-bg) 0 50%, var(--sw-accent) 50% 100%);
  box-shadow: 0 0 0 1px var(--sw-panel), 0 0 0 3px rgba(var(--accent-rgb), .25);
}
/* a gentle cross-fade while the palette changes */
.theme-fade, .theme-fade *, .theme-fade *::before, .theme-fade *::after {
  transition: background-color .5s ease, color .5s ease, border-color .5s ease, fill .5s ease, stroke .5s ease !important;
}

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 60px 70px;
  background: rgba(var(--bg-rgb), .95);
  backdrop-filter: blur(6px);
  animation: fade .35s var(--ease);
}
.lightbox[hidden] { display: none; }
.lightbox figure { margin: 0; text-align: center; max-width: 100%; }
.lightbox img {
  max-width: 100%; max-height: calc(100vh - 160px);
  margin: 0 auto;
  border: 1px solid var(--line);
}
.lightbox figcaption {
  margin-top: 18px;
  font-size: .72rem; font-weight: 400;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--gold-light);
}
.lb-close, .lb-nav {
  position: absolute;
  background: none; border: 1px solid var(--line);
  color: var(--gold-light);
  cursor: pointer;
  width: 48px; height: 48px;
  font-size: 1.6rem; line-height: 1;
  transition: border-color .3s, background .3s;
}
.lb-close:hover, .lb-nav:hover { border-color: var(--gold); background: rgba(var(--accent-rgb), .1); }
.lb-close { top: 18px; right: 18px; }
.lb-nav { top: 50%; transform: translateY(-50%); }
.lb-prev { left: 12px; }
.lb-next { right: 12px; }
@keyframes fade { from { opacity: 0; } }

/* ---------- Reveal on scroll ---------- */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
}
.js .reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
  .t-cur { animation: none; }

  /* hero: show the finished composition, no movement */
  .js .hero-photo img { opacity: 1; transform: none; animation: none !important; }
  .js .q-mark, .js .q-text, .js .hero-quote cite { opacity: 1; transform: none; filter: none; animation: none !important; }
  .q-foil { animation: none !important; }
  .js .hero-texture { opacity: 1; animation: none !important; }
  .hero-quote, .hero-photo { translate: none; opacity: 1; }
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 960px) {
  .nav-toggle { display: block; }
  .nav-links {
    position: fixed; inset: 0;
    z-index: -1;
    flex-direction: column; justify-content: center;
    gap: 30px;
    background: rgba(var(--bg-rgb), .98);
    opacity: 0; visibility: hidden;
    transition: opacity .4s var(--ease), visibility .4s;
  }
  .nav-links.open { opacity: 1; visibility: visible; }
  /* backdrop-filter would make the fixed menu size to the bar, so drop it while open */
  .nav.menu-open { backdrop-filter: none; -webkit-backdrop-filter: none; background: transparent; border-bottom-color: transparent; }
  .nav-links a { font-size: .95rem; }

  /* hero: the proverb takes the dark at the top, he stands in the lower part */
  .hero { align-items: flex-start; padding: 96px var(--gutter) 0; }
  .hero-photo { top: auto; height: 60svh; }
  .hero-photo img { object-position: 71% 100%; }
  .hero-photo::after {
    background:
      linear-gradient(to bottom, var(--ink), transparent 30%, transparent 92%, var(--ink)),
      linear-gradient(to right, var(--ink), transparent 8%, transparent 94%, var(--ink));
  }
  .hero::after { left: 50%; top: 22%; width: 120vw; height: 120vw; }
  .hero-quote { max-width: none; }
  .q-mark { font-size: clamp(4rem, 16vw, 6rem); }
  .q-text { font-size: clamp(1.45rem, 6.4vw, 2.1rem); }
  .hero-quote cite { margin-top: 20px; }

  .portrait { width: min(92%, 420px); }

  .about-grid { grid-template-columns: 1fr; }

  .skills { grid-template-columns: 1fr 1fr; }
  .skill-figure { grid-column: 1 / -1; order: -1; justify-self: center; width: min(62vw, 260px); margin-bottom: 8px; }

  .cert-grid { grid-template-columns: 1fr; }
  .project, .project.is-flip { grid-template-columns: 1fr; }
  .project.is-flip .project-media { order: 0; }
  .project-media { max-width: 620px; }

  .community > article { flex-basis: 100%; }
}

@media (max-width: 640px) {
  .theme-dock { right: 14px; bottom: 14px; }
  body { font-size: 16px; }
  .hero-frame { inset: 10px; }

  .timeline::before { left: 32px; }
  .timeline li { grid-template-columns: 64px 1fr; gap: 18px; align-items: start; }
  .tl-node { width: 64px; height: 64px; box-shadow: 0 0 0 4px var(--ink), 0 0 0 5px var(--line); }
  .medallion { width: 54px; height: 54px; padding: 5px; }
  .medallion.wide { padding: 10px 4px; }
  .tl-card { padding: 22px 20px; }

  .skills { grid-template-columns: 1fr; }
  .skill-col:first-child { text-align: left; }
  .skill-col:first-child li:hover { padding-right: 0; padding-left: 10px; }

  .honours li { grid-template-columns: 1fr; gap: 4px; padding: 24px 4px; }

  .site-banner { flex-direction: column; align-items: flex-start; }
  .sb-cta, .sb-cta .btn { width: 100%; }
  .socials { grid-template-columns: 1fr 1fr; gap: 12px; }
  .env-scene { margin-left: -6px; margin-right: -6px; }
  .env-letter { width: 94%; }
  .paper-actions .btn { flex: 1 1 100%; }
  .project { padding: 26px 20px 30px; }
  .project-media::before, .project.is-flip .project-media::before { inset: 10px -8px -10px 8px; }
  .term { font-size: .7rem; padding: 16px; }
  .project-links .btn { width: 100%; }

  .lightbox { padding: 60px 12px 90px; }
  .lb-nav { top: auto; bottom: 20px; transform: none; }
  .lb-prev { left: calc(50% - 60px); }
  .lb-next { right: calc(50% - 60px); }
}
