/* KL Design System — shared interior page styles.
   Extracted from the Squarespace custom-css-new.txt for standalone use
   (this static build has no Squarespace homepage/footer to scope around,
   so the .kl-page wrapper class is kept only for selector compatibility). */

/* Minimal reset: Squarespace's own base template zeroes out the browser's
   default 8px body margin for every site: this custom-css file never had to
   do it, since it only ever loaded on top of that base template. Outside
   Squarespace, the default margin shows through as a white gap around the
   full-bleed header. */
html, body { margin: 0; padding: 0; }
*, *::before, *::after { box-sizing: border-box; }

/* =========================================================
   KL DESIGN SYSTEM  (shared across all interior pages)
   Scope: everything is nested under .kl-page so the homepage
   (which has no .kl-page wrapper) is never affected.
   Palette: clean white + purple accents. Open Sans for text,
   JetBrains Mono for small labels/brand (terminal identity).
   ========================================================= */

.kl-page {
  --ink: #0e1526;
  --ink-soft: #46536b;
  --ink-faint: #75839a;
  --line: #ece9f2;
  --paper: #ffffff;
  --bg: #ffffff;
  --bg-tint: #f7f8fa;
  --purple-bright: #9B30FF;
  --purple-mid: #7c3aed;
  --purple-deep: #6d28d9;
  --accent: #7c3aed;
  --accent-ink: #6d28d9;
  --accent-soft: #f3edfd;
  --accent-soft-bd: #e3d7fa;
  --sunset: linear-gradient(120deg, #9B30FF, #7c3aed 55%, #6d28d9);
  --radius-lg: 26px;
  --radius: 18px;
  --shadow-1: 0 2px 4px rgba(16,25,45,.03), 0 12px 30px -10px rgba(16,25,45,.10);
  --shadow-2: 0 3px 8px rgba(16,25,45,.04), 0 24px 50px -16px rgba(16,25,45,.15);
  --shadow-3: 0 14px 32px -12px rgba(16,25,45,.14), 0 44px 80px -22px rgba(16,25,45,.22);
  --spring: cubic-bezier(.2,.8,.2,1);
  --gap: 20px;

  font-family: 'Open Sans', system-ui, sans-serif !important;
  color: var(--ink) !important;
  background:
    radial-gradient(1100px 460px at 84% -14%, rgba(124,58,237,.045), transparent 60%),
    var(--bg) !important;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Push the footer to the bottom of the viewport on short pages instead
     of leaving it floating right under the content with a gap below. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.kl-page > main { flex: 1 0 auto; }
.kl-page *, .kl-page *::before, .kl-page *::after { box-sizing: border-box; }
.kl-page h1, .kl-page h2, .kl-page h3 {
  font-family: 'Open Sans', sans-serif !important; font-weight: 800 !important;
  letter-spacing: -.025em; line-height: 1.06; margin: 0; color: var(--ink);
}
/* Kill the leftover homepage terminal blinking cursor on interior headings */
.kl-page h1::after, .kl-page h2::after, .kl-page h3::after { display: none !important; }
.kl-page img { max-width: 100%; display: block; }
.kl-page a { color: inherit; }
.kl-wrap { width: 92vw; max-width: 1180px; margin: 0 auto; }
/* Offset in-page anchor jumps so the target clears the sticky nav bar */
.kl-page [id] { scroll-margin-top: 92px; }

/* Pill / cell label -------------------------------------------------- */
.kl-page .kl-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font: 700 11px/1 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent-ink); background: var(--accent-soft); border: 1px solid var(--accent-soft-bd);
  padding: 7px 11px; border-radius: 8px;
}

/* Buttons ------------------------------------------------------------ */
.kl-page .kl-btn {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
  font: 600 14px/1 'Open Sans'; padding: 13px 22px; border-radius: 999px;
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
  transition: transform .25s var(--spring), box-shadow .25s var(--spring); box-shadow: var(--shadow-1); cursor: pointer;
}
.kl-page .kl-btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.kl-page .kl-btn.is-secondary { background: #fff; color: var(--ink); border-color: #d3d8e2; box-shadow: var(--shadow-1); }
.kl-page .kl-btn.is-secondary:hover { border-color: var(--accent); background: #fff; }

/* =========================================================
   SHARED HEADER (existing .kl-cloud-* markup, restyled)
   Sticky; shrinks + frosts when .kl-page gains .is-scrolled
   ========================================================= */
/* Solid dark top bar (AWS-style), full width, sticky + shrinks on scroll */
.kl-page .kl-cloud-header {
  position: sticky; top: 0; z-index: 100; padding: 14px 0; background: var(--ink);
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.06);
  transition: padding .3s var(--spring), box-shadow .3s var(--spring);
}
.kl-page.is-scrolled .kl-cloud-header { padding: 8px 0; box-shadow: 0 8px 24px rgba(0,0,0,.28); }
.kl-page .kl-cloud-header-inner { width: 92vw; max-width: 1180px; margin: 0 auto; display: flex; align-items: center; gap: 22px; }
.kl-page .kl-cloud-brand { display: flex; align-items: center; gap: 12px; text-decoration: none; margin-right: auto; }
.kl-page .kl-cloud-brand-mark {
  display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px;
  background: var(--accent); color: #fff; font: 700 15px/1 'JetBrains Mono';
  transition: all .3s var(--spring);
}
.kl-page.is-scrolled .kl-cloud-brand-mark { width: 34px; height: 34px; border-radius: 10px; font-size: 13px; }
.kl-page .kl-cloud-brand-text strong { display: block; font: 700 15px/1.1 'JetBrains Mono'; color: #ffffff; }
.kl-page .kl-cloud-brand-text span { display: block; font: 400 11.5px/1 'JetBrains Mono'; color: #9aa6b8; }
.kl-page.is-scrolled .kl-cloud-brand-text span { display: none; }
.kl-page .kl-cloud-nav { display: flex; align-items: center; gap: 4px; }
.kl-page .kl-cloud-nav > a, .kl-page .kl-cloud-dropdown > button {
  position: relative; text-decoration: none; color: #c7cfdd; font: 600 14px/1 'Open Sans';
  padding: 10px 14px; border-radius: 10px; background: transparent; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color .2s var(--spring), background .2s var(--spring);
}
.kl-page .kl-cloud-nav > a:hover, .kl-page .kl-cloud-dropdown > button:hover { color: #ffffff; background: rgba(255,255,255,.08); }
.kl-page .kl-cloud-nav > a.is-active { color: #ffffff; font-weight: 700; }
.kl-page .kl-cloud-nav > a.is-active::after { content: ""; position: absolute; left: 14px; right: 14px; bottom: 3px; height: 3px; background: #a855f7; border-radius: 3px; }
.kl-page .kl-cloud-dropdown { position: relative; }
.kl-page .kl-cloud-dropdown-menu {
  position: absolute; top: calc(100% + 8px); left: 0; min-width: 200px; padding: 8px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-2);
  display: grid; gap: 2px; opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: all .22s var(--spring);
}
/* The menu floats 8px below the button, and open/close is purely
   hover-driven - that gap used to be dead space where the pointer left
   both the button's box and the menu's box while moving between them,
   closing the dropdown before you could reach an item. This invisible
   strip fills exactly that gap; since it's part of the menu (a descendant
   of .kl-cloud-dropdown), hovering it keeps the dropdown open the whole
   way down. */
.kl-page .kl-cloud-dropdown-menu::before {
  content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px;
}
.kl-page .kl-cloud-dropdown:hover .kl-cloud-dropdown-menu,
.kl-page .kl-cloud-dropdown:focus-within .kl-cloud-dropdown-menu,
.kl-page .kl-cloud-dropdown.is-open .kl-cloud-dropdown-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.kl-page .kl-cloud-dropdown-menu a { text-decoration: none; color: var(--ink-soft); font: 500 13.5px/1 'Open Sans'; padding: 10px 12px; border-radius: 9px; transition: all .18s; }
.kl-page .kl-cloud-dropdown-menu a:hover { background: var(--accent-soft); color: var(--accent-ink); }
/* External-link icon (box + breakout arrow), added by decorateExternalLinks()
   in site.js next to any link that opens in a new tab: nav (Resume,
   Interactive Projects), hero action buttons, project card links, credit
   links, and Creative Coding modal links. Uses currentColor so it inherits
   each link's normal/hover color automatically. .kl-btn already has its own
   flex gap, so only the non-flex contexts need an explicit margin. */
.kl-page .kl-external-icon { vertical-align: -1px; opacity: .55; flex-shrink: 0; transition: opacity .18s; }
.kl-page .kl-cloud-dropdown-menu .kl-external-icon,
.kl-page .kl-card-links .kl-external-icon,
.kl-page .kl-mini .kl-external-icon,
.kl-page .cc-modal-links .kl-external-icon { margin-left: 5px; }
.kl-page .kl-cloud-nav > a:hover .kl-external-icon,
.kl-page .kl-cloud-dropdown-menu a:hover .kl-external-icon,
.kl-page .kl-btn:hover .kl-external-icon,
.kl-page .kl-card-links a:hover .kl-external-icon,
.kl-page .kl-mini a:hover .kl-external-icon,
.kl-page .cc-modal-links a:hover .kl-external-icon { opacity: 1; }
.kl-page .kl-cloud-socials { display: flex; gap: 6px; }
.kl-page .kl-cloud-socials a { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 11px; color: #c7cfdd; border: 1px solid rgba(255,255,255,.2); background: transparent; transition: all .22s var(--spring); }
.kl-page .kl-cloud-socials a:hover { color: #ffffff; border-color: var(--accent); transform: translateY(-2px); }

/* =========================================================
   SHARED FOOTER (rendered by initFooter() in site.js)
   Dark bar matching the header, bookending the light content
   below it. Kept deliberately simple: just a centered "Connect"
   section with real, readable link text (no repeat of the
   header's brand/wordmark), plus a distinct, darker bottom
   strip for the copyright line.
   ========================================================= */
.kl-page .kl-cloud-footer { background: var(--ink); margin-top: auto; }
.kl-page .kl-cloud-footer-inner {
  width: 92vw; max-width: 1180px; margin: 0 auto; padding: 44px 0 36px;
  display: flex; justify-content: center;
}
.kl-page .kl-cloud-footer-connect { text-align: center; }
.kl-page .kl-cloud-footer-label { display: block; font: 700 11px/1 'JetBrains Mono'; letter-spacing: .12em; text-transform: uppercase; color: #9B7BFF; margin-bottom: 14px; }
.kl-page .kl-cloud-footer-links { display: grid; gap: 9px; justify-items: start; }
.kl-page .kl-cloud-footer-links a {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
  font: 600 13.5px/1 'Open Sans'; color: #c7cfdd; transition: color .18s;
}
.kl-page .kl-cloud-footer-links a svg { flex-shrink: 0; opacity: .75; }
.kl-page .kl-cloud-footer-links a svg.kl-cloud-footer-icon-white { color: #ffffff; opacity: .9; }
.kl-page .kl-cloud-footer-links a:hover { color: #ffffff; }
.kl-page .kl-cloud-footer-links a:hover svg { opacity: 1; }
.kl-page .kl-cloud-footer-links .kl-cloud-footer-platform { color: #7a8299; font-weight: 500; }
.kl-page .kl-cloud-footer-bottom {
  background: rgba(0,0,0,.22); padding: 16px 0;
  font: 500 12px/1 'JetBrains Mono'; color: #7a8299; text-align: center;
}

/* Section divider (gray band, curve arches up toward center) --------- */
.kl-page .kl-divider { position: relative; width: 100%; height: 72px; line-height: 0; background: var(--bg-tint); }
.kl-page .kl-divider svg { width: 100%; height: 100%; display: block; }
.kl-page .kl-band { background: var(--bg-tint); }
.kl-page .kl-band-inner { padding: 26px 0 84px; }

/* Generic section heading (pill above, left aligned) ----------------- */
.kl-page .kl-head { margin-bottom: 20px; text-align: left; }
.kl-page .kl-head .kl-pill { margin-bottom: 12px; }
.kl-page .kl-head h2 { font-size: clamp(28px, 3.6vw, 42px); }

/* =========================================================
   PROJECTS PAGE
   ========================================================= */
.kl-page .kl-projects-hero { padding: 18px 0 24px; }
.kl-page .kl-projects-hero h1 { font-size: clamp(46px, 6.4vw, 82px); margin: 0 0 16px; }
.kl-page .kl-projects-hero p { max-width: 620px; font-size: 17px; color: var(--ink-soft); margin: 0; }

.kl-page .kl-feature-section { padding: 6px 0 40px; }
.kl-page .kl-feature-section > h2 { font-size: clamp(28px, 3.6vw, 40px); margin-bottom: 20px; }
.kl-page .kl-feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.kl-page .kl-feature-card {
  position: relative; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  overflow: hidden; text-decoration: none; color: inherit; box-shadow: var(--shadow-1);
  transition: transform .4s var(--spring), box-shadow .4s var(--spring), border-color .4s; display: flex; flex-direction: column;
}
.kl-page .kl-feature-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-3); border-color: var(--accent-soft-bd); }
.kl-page .kl-feature-media { aspect-ratio: 16/9; overflow: hidden; background: var(--bg-tint); }
.kl-page .kl-feature-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--spring); }
.kl-page .kl-feature-card:hover .kl-feature-media img { transform: scale(1.06); }
/* Per-card preview crops */
.kl-page .kl-feature-media.is-photo img { object-position: center 40%; }        /* keep the board/screen, trim the foot */
.kl-page .kl-feature-media.is-logo { background: #ffffff; }                      /* clean white behind the logo */
.kl-page .kl-feature-media.is-logo img { object-fit: contain; padding: 6% 8%; } /* show the full wordmark */
.kl-page .kl-feature-copy { padding: 15px 20px 18px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.kl-page .kl-feature-copy h2 { font-size: 20px; }
.kl-page .kl-feature-copy p { font-size: 14px; color: var(--ink-soft); margin: 0; }
.kl-page .kl-feature-copy .kl-more { font: 600 13px/1 'Open Sans'; color: var(--ink); display: inline-flex; align-items: center; gap: 6px; margin-top: 2px; }
.kl-page .kl-feature-copy .kl-more .kl-arrow { transition: transform .3s var(--spring); }
.kl-page .kl-feature-card:hover .kl-more .kl-arrow { transform: translateX(4px); }

/* Reel (project archive + about video) ------------------------------- */
.kl-page .kl-reel-panel { position: relative; background: var(--paper); border: 1px solid var(--line); border-radius: 30px; box-shadow: var(--shadow-2); padding: 30px 22px 34px; }
.kl-page .kl-reel-head { margin-bottom: 18px; padding: 0 6px; text-align: left; }
.kl-page .kl-reel-head .kl-pill { margin-bottom: 12px; }
.kl-page .kl-reel-head h2 { font-size: clamp(28px, 4vw, 44px); }
.kl-page .kl-reel-viewport { position: relative; padding: 0 64px; }
.kl-page .kl-reel-window { overflow: hidden; padding: 30px; }
.kl-page .kl-reel-track { display: flex; gap: var(--gap); transition: transform .55s var(--spring); will-change: transform; }
/* The video reel swaps between very different-looking full-bleed slides (no
   partial neighboring cards visible like "More Projects" has), so it reads
   as an abrupt cut unless it's noticeably slower than the card reels. */
.kl-page .kl-video-reel .kl-reel-track { transition-duration: .85s; }
.kl-page .kl-reel-card {
  position: relative; flex: 0 0 calc((100% - 40px) / 3); aspect-ratio: 4 / 5; border-radius: 22px;
  overflow: hidden; text-decoration: none; color: #fff; box-shadow: var(--shadow-1);
  transition: transform .45s var(--spring), box-shadow .45s var(--spring); isolation: isolate;
}
.kl-page .kl-reel-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; transition: transform .7s var(--spring); }
.kl-page .kl-reel-card::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(10,16,30,0) 26%, rgba(10,16,30,.45) 56%, rgba(10,16,30,.93) 100%); }
.kl-page .kl-reel-card:hover { transform: translateY(-10px); box-shadow: 0 24px 50px -16px rgba(16,25,45,.30), 0 0 0 3px rgba(124,58,237,.35); }
.kl-page .kl-reel-card:hover img { transform: scale(1.07); }
.kl-page .kl-reel-info { position: absolute; left: 0; right: 0; bottom: 0; padding: 20px 18px; display: flex; flex-direction: column; align-items: flex-start; gap: 9px; }
.kl-page .kl-reel-info .kl-type { font: 700 10.5px/1.35 'JetBrains Mono'; letter-spacing: .11em; text-transform: uppercase; color: #fff; background: rgba(101,72,168,.9); border: 1px solid rgba(255,255,255,.24); padding: 8px 13px; border-radius: 9px; }
.kl-page .kl-reel-info h3 { font-size: 22px; color: #fff; }
.kl-page .kl-reel-info p { font-size: 13.5px; color: rgba(255,255,255,.88); margin: 0; max-height: 0; opacity: 0; overflow: hidden; transition: max-height .45s var(--spring), opacity .35s, margin .45s; }
.kl-page .kl-reel-info .kl-rlink { display: inline-flex; align-items: center; gap: 6px; font: 600 13px/1 'Open Sans'; color: #fff; max-height: 0; opacity: 0; overflow: hidden; transition: max-height .45s var(--spring), opacity .35s; }
.kl-page .kl-reel-card:hover .kl-reel-info p { max-height: 140px; opacity: 1; margin-top: 2px; }
.kl-page .kl-reel-card:hover .kl-reel-info .kl-rlink { max-height: 40px; opacity: 1; }
.kl-page .kl-reel-arrow { position: absolute; top: 44%; transform: translateY(-50%); z-index: 5; width: 48px; height: 48px; border-radius: 50%; border: 1.5px solid #cbd2df; background: var(--paper); color: var(--ink); font-size: 22px; font-weight: 700; line-height: 1; cursor: pointer; display: grid; place-items: center; box-shadow: 0 8px 20px rgba(16,25,45,.18), 0 2px 5px rgba(16,25,45,.12); transition: transform .2s var(--spring), opacity .2s, background .2s, color .2s, border-color .2s; }
.kl-page .kl-reel-arrow:hover { transform: translateY(-50%) scale(1.08); background: var(--accent); color: #fff; border-color: var(--accent); box-shadow: 0 10px 24px rgba(124,58,237,.34); }
.kl-page .kl-reel-arrow.is-prev { left: 4px; } .kl-page .kl-reel-arrow.is-next { right: 4px; }
.kl-page .kl-reel-arrow[disabled] { opacity: .28; pointer-events: none; }
.kl-page .kl-reel-dots { display: flex; justify-content: center; gap: 7px; margin-top: 18px; }
.kl-page .kl-reel-dots button { width: 8px; height: 8px; border-radius: 50%; border: 0; background: #dfe1e6; cursor: pointer; padding: 0; transition: all .25s var(--spring); }
.kl-page .kl-reel-dots button.is-active { background: var(--accent); width: 22px; border-radius: 4px; }

/* =========================================================
   PROJECT DETAIL PAGES  (.kl-pd-*)
   ========================================================= */
.kl-page .kl-pd-hero { padding: 20px 0 22px; display: grid; grid-template-columns: 1.35fr 1fr; gap: 30px; align-items: stretch; }
.kl-page .kl-pd-hero-main { display: flex; flex-direction: column; align-items: flex-start; }
.kl-page .kl-pd-hero h1 { font-size: clamp(42px, 5.8vw, 70px); margin: 14px 0 16px; }
.kl-page .kl-pd-lead { font-size: 17px; color: var(--ink-soft); max-width: 560px; margin: 0; }
.kl-page .kl-pd-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 22px; }
.kl-page .kl-status { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow-1); transition: transform .35s var(--spring), box-shadow .35s var(--spring); }
.kl-page .kl-status:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }
.kl-page .kl-status > strong { display: block; font: 800 20px/1.1 'Open Sans'; letter-spacing: -.02em; margin: 10px 0 6px; color: var(--ink); }
.kl-page .kl-status > p { font-size: 13.5px; color: var(--ink-soft); margin: 0; }
.kl-page .kl-pd-hero-main .kl-status { margin-top: auto; align-self: stretch; }
.kl-page .kl-pd-side { display: grid; gap: 14px; }

.kl-page .kl-panel { margin: 20px 0; padding: 32px; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-1); }
.kl-page .kl-panel-head { margin-bottom: 22px; text-align: left; }
.kl-page .kl-panel-head .kl-pill { margin-bottom: 12px; }
.kl-page .kl-panel-head h2 { font-size: clamp(24px, 3.4vw, 34px); }
.kl-page .kl-video { border-radius: var(--radius); overflow: hidden; aspect-ratio: 16/9; background: var(--bg-tint); border: 1px solid var(--line); }
.kl-page .kl-video iframe { width: 100%; height: 100%; border: 0; }
.kl-page .kl-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.kl-page .kl-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.kl-page .kl-mini { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; transition: transform .35s var(--spring), box-shadow .35s var(--spring), background .35s; }
.kl-page .kl-mini:hover { transform: translateY(-5px); box-shadow: var(--shadow-2); }
.kl-page .kl-mini-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.kl-page .kl-mini-top strong { font: 700 22px/1 'JetBrains Mono'; color: var(--line); }
.kl-page .kl-mini h3 { font-size: 17px; margin-bottom: 10px; color: var(--ink); }
.kl-page .kl-mini p, .kl-page .kl-mini li { font-size: 13.5px; color: var(--ink-soft); }
.kl-page .kl-mini ul { margin: 0; padding-left: 18px; display: grid; gap: 5px; }
.kl-page .kl-tech { display: flex; flex-wrap: wrap; gap: 10px; }
.kl-page .kl-tech span { font: 600 13px/1 'Open Sans'; padding: 10px 16px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-ink); border: 1px solid var(--accent-soft-bd); }

/* Expandable project-board cards (current & future projects) */
.kl-page .kl-mini details { margin-top: 12px; }
.kl-page .kl-mini summary { cursor: pointer; font: 600 13px/1 'Open Sans'; color: var(--accent-ink); list-style: none; display: inline-flex; align-items: center; gap: 6px; }
.kl-page .kl-mini summary::-webkit-details-marker { display: none; }
.kl-page .kl-mini summary::after { content: "＋"; font-weight: 700; }
.kl-page .kl-mini details[open] summary::after { content: "－"; }
.kl-page .kl-mini details > div { margin-top: 10px; }
.kl-page .kl-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.kl-page .kl-card-tags em { font-style: normal; font: 600 11px/1 'JetBrains Mono'; color: var(--accent-ink); background: var(--accent-soft); border: 1px solid var(--accent-soft-bd); padding: 5px 8px; border-radius: 6px; }
.kl-page .kl-card-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; }
.kl-page .kl-card-links a { font: 600 12.5px/1 'Open Sans'; color: var(--accent-ink); text-decoration: none; }
.kl-page .kl-card-links a:hover { text-decoration: underline; }
.kl-page .kl-mini-flow { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.kl-page .kl-mini-flow span { font: 600 11px/1 'JetBrains Mono'; color: var(--ink-soft); background: var(--bg-tint); border: 1px solid var(--line); padding: 5px 8px; border-radius: 6px; }

/* Creative-coding archive: clickable image cards that open a popup (driven by footer JS) */
.kl-page .cc-modal-trigger { text-align: left; font: inherit; color: inherit; cursor: pointer; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; display: block; width: 100%; transition: transform .35s var(--spring), box-shadow .35s var(--spring), background .35s; }
.kl-page .cc-modal-trigger:hover { transform: translateY(-5px); background: var(--paper); box-shadow: var(--shadow-2); }
.kl-page .cc-modal-trigger h3 { font-size: 17px; margin-bottom: 8px; color: var(--ink); }
.kl-page .cc-modal-trigger p { font-size: 13.5px; color: var(--ink-soft); margin: 0; }
.kl-page .cc-modal-trigger em { display: inline-block; margin-top: 10px; font-style: normal; font: 600 12.5px/1.4 'Open Sans'; color: var(--accent-ink); }
.kl-page .kl-cc-media { margin: -20px -20px 14px; border-radius: var(--radius) var(--radius) 0 0; overflow: hidden; aspect-ratio: 16/10; background: var(--bg-tint); }
.kl-page .kl-cc-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Popup modal (opens over the page, does not push layout) */
.kl-page #cc-project-modal { position: fixed; inset: 0; z-index: 1000; display: none; }
.kl-page #cc-project-modal.is-open { display: flex; align-items: center; justify-content: center; }
.kl-page .cc-modal-backdrop { position: absolute; inset: 0; background: rgba(10,16,30,.55); }
.kl-page .cc-modal-panel { position: relative; z-index: 1; width: 92vw; max-width: 640px; max-height: 86vh; overflow: auto; margin: auto; background: #fff; border-radius: 22px; box-shadow: var(--shadow-3); padding: 30px 30px 34px; }
.kl-page .cc-modal-close { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line); background: #fff; color: var(--ink); font-size: 20px; line-height: 1; cursor: pointer; transition: all .2s var(--spring); }
.kl-page .cc-modal-close:hover { background: var(--ink); color: #fff; }
.kl-page .cc-modal-header p { font: 700 11px/1 'JetBrains Mono'; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-ink); margin: 0 0 8px; }
.kl-page .cc-modal-header h2 { font-size: clamp(24px, 4vw, 32px); margin: 0 0 16px; }
.kl-page .cc-modal-links { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.kl-page .cc-modal-links a { font: 600 13px/1 'Open Sans'; text-decoration: none; color: #fff; background: var(--ink); padding: 10px 16px; border-radius: 999px; }
.kl-page .cc-modal-links a:hover { background: var(--accent); }
.kl-page #cc-modal-body p { font-size: 14.5px; color: var(--ink-soft); margin: 0 0 12px; }
.kl-page #cc-modal-body h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--accent-ink); margin: 16px 0 6px; }
.kl-page #cc-modal-body ul { margin: 0 0 12px; padding-left: 18px; display: grid; gap: 5px; }
.kl-page #cc-modal-body li { font-size: 14px; color: var(--ink-soft); word-break: break-word; }
body.cc-modal-lock { overflow: hidden; }

/* Generic info popup (About video reel "More info"), reuses the modal styling */
.kl-page #kl-info-modal { position: fixed; inset: 0; z-index: 1000; display: none; }
.kl-page #kl-info-modal.is-open { display: flex; align-items: center; justify-content: center; }
.kl-page #kl-info-modal .cc-modal-body { font-size: 14.5px; color: var(--ink-soft); line-height: 1.6; }
.kl-page .kl-info-btn { margin-top: 12px; font: 600 13px/1 'Open Sans'; color: var(--accent-ink); background: none; border: 0; padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.kl-page .kl-info-btn:hover { text-decoration: underline; }

/* Image lightbox: click-to-enlarge popup for standalone content images on
   project detail pages (screenshots, photos). Not used for images that are
   already inside a link or another button - see initLightbox() in site.js. */
.kl-page img.kl-zoomable { cursor: zoom-in; transition: transform .3s var(--spring), box-shadow .3s var(--spring); }
.kl-page img.kl-zoomable:hover, .kl-page img.kl-zoomable:focus-visible { transform: scale(1.015); box-shadow: var(--shadow-2); }
/* Not scoped under .kl-page: the lightbox is appended straight to <body> by
   site.js (see initLightbox), and .kl-page is a div inside body, not body
   itself - a .kl-page-scoped rule here would never match it. */
.kl-lightbox { position: fixed; inset: 0; z-index: 1000; display: none; }
.kl-lightbox.is-open { display: flex; align-items: center; justify-content: center; }
.kl-lightbox-backdrop { position: absolute; inset: 0; background: rgba(10,16,30,.96); cursor: zoom-out; }
.kl-lightbox-panel { position: relative; z-index: 1; width: 92vw; max-width: 1100px; max-height: 88vh; margin: auto; }
.kl-lightbox-panel img { display: block; width: 100%; height: 100%; max-height: 88vh; object-fit: contain; border-radius: 12px; box-shadow: var(--shadow-3); }
.kl-lightbox-close { position: absolute; top: -44px; right: 0; width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(255,255,255,.4); background: rgba(255,255,255,.12); color: #fff; font-size: 20px; line-height: 1; cursor: pointer; transition: all .2s var(--spring); }
.kl-lightbox-close:hover { background: #fff; color: var(--ink); }

/* Closing "keep exploring" cross-nav (light, on-theme) --------------- */
.kl-page .kl-explore { margin: 28px 0 84px; padding: 32px; background: linear-gradient(135deg, #f6f2fd 0%, #f0ebfb 100%); color: var(--ink); border: 1px solid var(--accent-soft-bd); border-radius: 30px; box-shadow: var(--shadow-1); }
.kl-page .kl-explore-head { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 22px; flex-wrap: wrap; }
.kl-page .kl-explore-head h2 { color: var(--ink); font-size: clamp(24px, 3vw, 34px); }
.kl-page .kl-explore .kl-pill { background: #fff; border-color: var(--accent-soft-bd); }
.kl-page .kl-explore .kl-btn.is-secondary { background: #fff; box-shadow: var(--shadow-1); border-color: var(--accent-soft-bd); }
.kl-page .kl-explore .kl-btn.is-secondary:hover { border-color: var(--accent); }
.kl-page .kl-explore-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.kl-page .kl-explore-card { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 18px 20px; border-radius: var(--radius); background: var(--paper); border: 1px solid var(--line); text-decoration: none; color: var(--ink); box-shadow: var(--shadow-1); transition: transform .3s var(--spring), box-shadow .3s, border-color .3s; }
.kl-page .kl-explore-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); border-color: var(--accent); }
.kl-page .kl-explore-card .kl-type { font: 700 10.5px/1.35 'JetBrains Mono'; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-ink); background: var(--accent-soft); border: 1px solid var(--accent-soft-bd); padding: 7px 11px; border-radius: 8px; }
.kl-page .kl-explore-card strong { font: 700 18px/1.2 'Open Sans'; color: var(--ink); }
.kl-page .kl-explore-card em { font-style: normal; font-size: 13px; color: var(--ink-soft); }
.kl-page .kl-explore-card .kl-go { margin-top: 4px; font: 600 12.5px/1 'Open Sans'; color: var(--accent-ink); display: inline-flex; align-items: center; gap: 5px; }
.kl-page .kl-explore-card .kl-go .kl-arrow { transition: transform .3s var(--spring); }
.kl-page .kl-explore-card:hover .kl-go .kl-arrow { transform: translateX(4px); }

/* =========================================================
   ABOUT PAGE
   ========================================================= */
.kl-page .kl-about-hero { padding: 22px 0 34px; display: grid; grid-template-columns: 1.3fr 1fr; gap: 40px; align-items: stretch; }
.kl-page .kl-about-copy .kl-pill { margin-bottom: 14px; }
.kl-page .kl-about-copy h1 { font-size: clamp(44px, 6vw, 76px); margin: 0 0 14px; }
.kl-page .kl-about-lead { font-size: 19px; font-weight: 600; color: var(--ink); margin: 0 0 14px; }
.kl-page .kl-about-body { font-size: 15.5px; color: var(--ink-soft); margin: 0 0 24px; max-width: 560px; }
.kl-page .kl-about-actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* Photo matches the height of the adjacent text column (grid stretch) */
.kl-page .kl-about-photo { position: relative; border-radius: 24px; overflow: hidden; border: 1px solid var(--line); box-shadow: var(--shadow-2); background: var(--bg-tint); }
/* Two stacked image layers crossfade into each other (no dip, no blank frame)
   while each one runs its own slow pan/zoom (Ken Burns) - see initKevinCloudAbout
   in site.js. Image is absolutely filled so its natural size never drives
   the box height - the box locks to the text column height and every photo
   crops into it. */
.kl-page .kl-about-photo-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 38%; display: block; opacity: 0; transition: opacity 1.4s ease; will-change: opacity, transform; }
.kl-page .kl-about-photo-img.is-active { opacity: 1; z-index: 1; }
.kl-page .kl-about-photo-img.kl-kb-a { animation: klKenBurnsA 6.6s linear forwards; }
.kl-page .kl-about-photo-img.kl-kb-b { animation: klKenBurnsB 6.6s linear forwards; }
@keyframes klKenBurnsA { from { transform: scale(1) translate(0, 0); } to { transform: scale(1.09) translate(-1.6%, -1%); } }
@keyframes klKenBurnsB { from { transform: scale(1.03) translate(1.2%, 1%); } to { transform: scale(1.1) translate(-1%, -1.6%); } }

.kl-page .kl-about-buckets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; padding-bottom: 6px; }
.kl-page .kl-bucket { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow-1); transition: transform .35s var(--spring), box-shadow .35s var(--spring); }
.kl-page .kl-bucket:hover { transform: translateY(-5px); box-shadow: var(--shadow-2); }
.kl-page .kl-bucket h2 { font-size: 16px; }
.kl-page .kl-bucket p { font-size: 13px; color: var(--ink-soft); margin: 0; flex: 1; }
.kl-page .kl-bucket a { margin-top: 2px; font: 600 12.5px/1 'Open Sans'; color: var(--accent-ink); text-decoration: none; display: inline-flex; align-items: center; gap: 5px; }

/* Full-block video reel (one video per view, side arrows) */
.kl-page .kl-vslide { flex: 0 0 100%; }
.kl-page .kl-vvideo { border-radius: var(--radius); overflow: hidden; aspect-ratio: 16/9; background: #000; border: 1px solid var(--line); }
.kl-page .kl-vvideo iframe { width: 100%; height: 100%; border: 0; display: block; }
.kl-page .kl-vcopy { padding: 16px 4px 0; }
.kl-page .kl-vcopy .kl-pill { margin-bottom: 10px; }
.kl-page .kl-vcopy h3 { font-size: 22px; margin-bottom: 8px; color: var(--ink); }
.kl-page .kl-vcopy p { font-size: 14.5px; color: var(--ink-soft); margin: 0; max-width: 760px; }

/* Education timeline */
.kl-page .kl-timeline { position: relative; display: grid; gap: 20px; padding-left: 26px; }
.kl-page .kl-timeline::before { content: ""; position: absolute; left: 6px; top: 8px; bottom: 8px; width: 2px; background: var(--line); }
.kl-page .kl-tnode { position: relative; }
/* Dot is gray by default and centered on the line; turns purple only on hover of that item */
.kl-page .kl-tnode::before { content: ""; position: absolute; left: -26px; top: 5px; width: 14px; height: 14px; border-radius: 50%; background: #cfd4de; box-shadow: 0 0 0 4px #fff; transition: background .25s var(--spring), box-shadow .25s var(--spring); }
.kl-page .kl-tnode:hover::before { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.kl-page .kl-tyear { font: 700 12px/1 'JetBrains Mono'; color: var(--accent-ink); margin-bottom: 10px; }
.kl-page .kl-tcard { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; transition: transform .35s var(--spring), box-shadow .35s var(--spring), background .35s, border-color .35s; }
.kl-page .kl-tnode:hover .kl-tcard { transform: translateY(-4px); background: var(--paper); box-shadow: var(--shadow-2); border-color: var(--accent-soft-bd); }
.kl-page .kl-tcard .kl-pill { margin-bottom: 10px; }
.kl-page .kl-tcard h3 { font-size: 16px; margin-bottom: 6px; color: var(--ink); }
.kl-page .kl-tcard p { font-size: 13.5px; color: var(--ink-soft); margin: 0; }

/* Skills */
.kl-page .kl-skills-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.kl-page .kl-skill-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow-1); transition: transform .35s var(--spring), box-shadow .35s var(--spring), border-color .35s; }
.kl-page .kl-skill-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-2); border-color: var(--accent-soft-bd); }
.kl-page .kl-skill-card h3 { font-size: 15px; margin-bottom: 12px; color: var(--ink); }
.kl-page .kl-skill-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.kl-page .kl-skill-tags span { font: 600 12px/1 'Open Sans'; padding: 6px 10px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-ink); border: 1px solid var(--accent-soft-bd); }

/* Quote */
.kl-page .kl-quote { margin: 20px 0 84px; padding: 44px 40px; background: linear-gradient(135deg, #f6f2fd 0%, #f0ebfb 100%); border: 1px solid var(--accent-soft-bd); border-radius: 30px; text-align: center; }
.kl-page .kl-quote blockquote { margin: 0; }
.kl-page .kl-quote blockquote p { font: 800 clamp(20px, 3vw, 28px)/1.4 'Open Sans'; letter-spacing: -.02em; color: var(--ink); margin: 0 0 14px; }
.kl-page .kl-quote cite { font: 600 14px/1 'JetBrains Mono'; color: var(--accent-ink); font-style: normal; }

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 940px) {
  .kl-page .kl-pd-hero { grid-template-columns: 1fr; }
  .kl-page .kl-grid-3, .kl-page .kl-feature-grid, .kl-page .kl-explore-grid { grid-template-columns: 1fr 1fr; }
  .kl-page .kl-reel-card { flex-basis: calc((100% - 20px) / 2); }
  .kl-page .kl-about-hero { grid-template-columns: 1fr; }
  .kl-page .kl-about-photo { aspect-ratio: 4 / 5; }   /* stacked: give the box a fixed height */
  .kl-page .kl-about-buckets { grid-template-columns: 1fr 1fr; }
  .kl-page .kl-skills-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 680px) {
  /* Single-row header on mobile. The Interactive Projects dropdown is hidden
     (several of those aren't usable on phones), so About/Projects/Resume plus
     the contact icons all fit on one line without clipping. */
  .kl-page .kl-cloud-brand-text { display: none; }
  .kl-page .kl-cloud-header-inner { gap: 8px; }
  .kl-page .kl-cloud-brand-mark { width: 36px; height: 36px; }
  .kl-page .kl-cloud-dropdown { display: none; }
  .kl-page .kl-cloud-nav { gap: 2px; }
  .kl-page .kl-cloud-nav > a { padding: 8px 9px; font-size: 13px; white-space: nowrap; }
  .kl-page .kl-cloud-nav > a.is-active::after { left: 9px; right: 9px; }
  .kl-page .kl-projects-hero { padding: 40px 0 22px; }
  .kl-page .kl-grid-3, .kl-page .kl-grid-2, .kl-page .kl-feature-grid, .kl-page .kl-explore-grid { grid-template-columns: 1fr; }
  .kl-page .kl-panel { padding: 22px; }
  .kl-page .kl-reel-viewport { padding: 0 8px; }
  .kl-page .kl-reel-window { padding: 20px 8px; }
  .kl-page .kl-reel-card { flex-basis: 100%; }
  .kl-page .kl-reel-arrow.is-prev { left: 6px; } .kl-page .kl-reel-arrow.is-next { right: 6px; }
  .kl-page .kl-pd-hero { padding-top: 34px; }
  .kl-page .kl-about-buckets, .kl-page .kl-skills-grid { grid-template-columns: 1fr; }
}
/* Very small phones: drop the contact icons so the nav stays on one line */
@media (max-width: 360px) {
  .kl-page .kl-cloud-socials { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* html[data-kl-force-motion] is a preview-only escape hatch (see site.js,
     ?motion=on) so this accessibility behavior can be reviewed without it -
     it's never present for a real visitor, who always gets this rule. */
  html:not([data-kl-force-motion]) .kl-page *,
  html:not([data-kl-force-motion]) .kl-page *::before,
  html:not([data-kl-force-motion]) .kl-page *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; }
}

/* =========================================================
   Scroll reveal: cards fade + rise as they enter the viewport.
   JS-gated (.js-reveal is added by script) so if scripts don't
   load, everything stays fully visible. Reduced-motion opts out.
   ========================================================= */
.kl-page.js-reveal .kl-reveal {
  opacity: 0; transform: translateY(20px);
  transition: opacity .6s var(--spring), transform .6s var(--spring);
  will-change: opacity, transform;
}
.kl-page.js-reveal .kl-reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .kl-page.js-reveal .kl-reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

.kl-page :focus-visible { outline: 3px solid #7c3aed; outline-offset: 2px; border-radius: 3px; }

