/* Additions on top of Framer's generated layout CSS. */

/* project card hover: image zoom eases like Framer's spring */
.framer-TjBKF .framer-1os7h0b { transition: width 0.55s cubic-bezier(0.25, 0.8, 0.3, 1), height 0.55s cubic-bezier(0.25, 0.8, 0.3, 1); }

/* custom cursor (desktop pointers only; created by site.js) */
.nh-cursor {
  position: fixed; top: 0; left: 0; z-index: 13; pointer-events: none;
  width: 26px; height: 26px; border-radius: 50%;
  background: #fff; mix-blend-mode: difference; opacity: 0;
  transition: width 0.4s cubic-bezier(0.25, 0.8, 0.3, 1), height 0.4s cubic-bezier(0.25, 0.8, 0.3, 1), opacity 0.2s;
}
.nh-cursor.is-on { opacity: 1; }
.nh-cursor.is-hover { width: 70px; height: 70px; }
@media (hover: none), (pointer: coarse) { .nh-cursor { display: none; } }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0s !important; }
}

/* ---------- Spatia project card: square, first in the grid like the others ---------- */
.nh-feature-cell { width: 100%; }
.nh-feature {
  position: relative; display: block; width: 100%; aspect-ratio: 1 / 1; overflow: hidden;
  background: #120d0a; color: #fff; text-decoration: none;
}
.nh-feature img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.55s cubic-bezier(0.25, 0.8, 0.3, 1);
}
.nh-feature-shade {
  position: absolute; inset: 0; opacity: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 100%);
  transition: opacity 0.55s cubic-bezier(0.25, 0.8, 0.3, 1);
}
.nh-feature-title {
  position: absolute; left: 48px; bottom: 50px; opacity: 0;
  font-family: "Inter", "Inter Placeholder", sans-serif; font-weight: 500;
  font-size: 48px; line-height: 1.2em; letter-spacing: -0.05em; color: #fff;
  transition: opacity 0.55s cubic-bezier(0.25, 0.8, 0.3, 1);
}
@media (hover: hover) and (pointer: fine) {
  .nh-feature:hover img { transform: scale(1.06); }
  .nh-feature:hover .nh-feature-shade, .nh-feature:hover .nh-feature-title { opacity: 1; }
}
.nh-feature:focus-visible { outline: 2px solid #000; outline-offset: 4px; }
.nh-feature:focus-visible .nh-feature-shade, .nh-feature:focus-visible .nh-feature-title { opacity: 1; }
@media (max-width: 1199.98px) { .nh-feature-title { left: 30px; bottom: 30px; font-size: 40px; } }
@media (max-width: 809.98px) { .nh-feature-title { display: none; } }

/* ---------- Live 360° panorama (replaces a video slot) ---------- */
.nh-pano {
  position: relative; width: 100%; height: 100%; overflow: hidden; background: #1a1612;
  cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none;
}
.nh-pano.is-dragging { cursor: grabbing; }
.nh-pano canvas, .nh-pano-poster {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover;
}
.nh-pano canvas { opacity: 0; transition: opacity 0.6s ease; }
.nh-pano.is-ready canvas { opacity: 1; }
.nh-pano-hint {
  position: absolute; left: 20px; bottom: 20px; padding: 8px 12px; border-radius: 6px;
  background: rgba(0, 0, 0, 0.55); color: #fff; pointer-events: none;
  font-family: "Inter", "Inter Placeholder", sans-serif; font-weight: 500; font-size: 14px; letter-spacing: -0.02em;
  transition: opacity 0.4s ease;
}
.nh-pano.is-touched .nh-pano-hint { opacity: 0; }
@media (max-width: 809.98px) {
  .nh-pano-hint { left: 10px; bottom: 10px; padding: 6px 9px; font-size: 12px; }
}
/* the slot was sized by the video it replaced; give the panorama the slot's full box */
[class*="-container"]:has(> .nh-pano) { height: 100% !important; width: 100% !important; flex: 1 0 0 !important; }

/* =====================================================================
   Intentional changes to the Framer original (content/edits.py).
   Scoped to .nh-v2, which only the normal build sets; the parity build
   renders the original exactly.
   ===================================================================== */
@font-face {
  font-family: "NH Inter Light"; font-style: normal; font-weight: 300; font-display: swap;
  src: url(../fonts/inter-300-latin.woff2) format("woff2");
}

/* exRevolut: "ex" set in Inter Light at the logo's lowercase height, on its baseline.
   The Revolut wordmark's x-height is 16.4% of the logo width and its baseline sits
   12.3% of the logo height above the image bottom. */
.nh-v2 .nh-exrow { display: flex; align-items: flex-end; --logo-w: 140px; }
.nh-v2 .nh-ex {
  font-family: "NH Inter Light", "Inter", sans-serif; font-weight: 300; color: #000;
  font-size: calc(var(--logo-w) * 0.3); line-height: 1; letter-spacing: -0.02em;
  margin-right: 0.05em;
  margin-bottom: calc(var(--logo-w) / 3.472 * 0.123 - 0.136em);
}
@media (max-width: 1199.98px) { .nh-v2 .nh-exrow { --logo-w: 120px; } }
@media (max-width: 809.98px) { .nh-v2 .nh-exrow { --logo-w: 75px; } }

/* Loughborough crest fills the same box the icon used */
.nh-v2 .nh-crest { display: block; width: 100%; height: 100%; object-fit: contain; }

/* Experience and Achievements: Nic's original styles (weights, letter-spacing,
   line-height all as on Framer), only scaled down proportionally:
   80% on desktop and tablet, about 82% on phones with a 13px floor for detail text. */
.nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) h5 { font-size: 24px !important; }
.nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) [data-framer-name="Text Section"] p,
.nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) [data-framer-name="Text Section"] p span { font-size: 18px !important; }
.nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) .framer-1wsbujl { width: 56px !important; height: 56px !important; flex: none !important; }
.nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) .framer-1wsbujl > * { width: 100% !important; height: 100% !important; }
@media (max-width: 809.98px) {
  .nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) h5 { font-size: 18px !important; }
  .nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) [data-framer-name="Text Section"] p,
  .nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) [data-framer-name="Text Section"] p span { font-size: 13px !important; }
  .nh-v2 :is(section[data-framer-name="Experience"], section[data-framer-name="Achievements"]) .framer-1wsbujl { width: 52px !important; height: 52px !important; }
}
/* deepmirror's tall, solid mark reads heavier than the others at the same box size */
.nh-v2 img[src*="deepmirror-logo"] { transform: scale(0.84); }

/* Spatia page: the template's three tall phone columns become full-width
   laptop-shaped rows (16:10 image, then title and text), at every width. */
[data-nh-page="spatia"] .framer-12fuao2 { flex-direction: column !important; gap: 72px !important; }
[data-nh-page="spatia"] .framer-12fuao2 [class*="-container"] { width: 100% !important; flex: none !important; height: auto !important; }
[data-nh-page="spatia"] .framer-btytsy { flex-direction: column !important; width: 100% !important; height: auto !important; gap: 20px !important; }
[data-nh-page="spatia"] .framer-1p7ient { width: 100% !important; height: auto !important; aspect-ratio: 16 / 10; flex: none !important; }
[data-nh-page="spatia"] .framer-1j0h9wu { width: 100% !important; height: 100% !important; }
[data-nh-page="spatia"] .framer-1j0h9wu img { object-fit: cover !important; }
@media (max-width: 809.98px) { [data-nh-page="spatia"] .framer-12fuao2 { gap: 48px !important; } }
[data-nh-page="spatia"] .framer-btytsy > * { width: 100% !important; flex: none !important; max-width: none !important; }
/* Spatia hero: a taller window (1.625:1 instead of the template's 2.04:1) so the
   laptop is bigger while the laptop and its plinth both stay in frame (Nic's note) */
[data-nh-page="spatia"] .framer-jvubps { height: auto !important; }
[data-nh-page="spatia"] .framer-9gitfk { aspect-ratio: 1.625 !important; height: auto !important; width: 100% !important; flex: none !important; }
[data-nh-page="spatia"] .framer-1l8h3qj { width: 100% !important; height: 100% !important; }
[data-nh-page="spatia"] .framer-1l8h3qj > div, [data-nh-page="spatia"] .framer-1l8h3qj > div > div { height: 100% !important; width: 100% !important; aspect-ratio: auto !important; }
}
/* Menu: opening it keeps the logo and the menu button exactly where they were.
   Framer's open variants have less top padding, so the bar jumped up 9.5px on
   tablets and 3.5px on phones when the menu opened (Nic: "top bar shifts weirdly"). */
.nh-v2 header.framer-8xYw9.framer-v-1c5dtbo.framer-14x3d1s { padding-top: 33.5px !important; }
.nh-v2 header.framer-8xYw9.framer-v-1xhzf5f.framer-14x3d1s { padding-top: 23.5px !important; }
/* Loading placeholders (site.js section 11): light grey with a soft sheen, then the image fades in */
.nh-v2 .nh-sk {
  background-color: #efefef !important;
  background-image: linear-gradient(100deg, rgba(255, 255, 255, 0) 35%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 65%) !important;
  background-size: 250% 100% !important; background-repeat: no-repeat !important;
  animation: nh-sheen 1.6s ease-in-out infinite;
}
@keyframes nh-sheen { from { background-position: 120% 0; } to { background-position: -20% 0; } }
.nh-v2 img.nh-fade { transition: opacity 0.5s ease; }
.nh-v2 img.nh-ld { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .nh-v2 .nh-sk { animation: none; } }
/* iPhones draw a play glyph over a muted autoplay video before it starts; the poster frame is enough */
.nh-v2 video::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
.nh-v2 video::-webkit-media-controls { display: none !important; }

/* Experience: role details revealed one at a time (site.js initXp, content/edits.py XP_DETAILS) */
.nh-v2 .nh-xp .framer-CGLio { cursor: pointer; }
.nh-v2 .nh-xp .framer-CGLio > :not(.nh-xp-line) { transition: opacity 0.5s cubic-bezier(0.25, 0.8, 0.3, 1); }
/* the timeline line stays at full strength when its row dims */
.nh-v2 .nh-xp.has-open .framer-CGLio:not(.is-open) > :not(.nh-xp-line) { opacity: 0.32; }
.nh-v2 .nh-xp .framer-CGLio:focus-visible { outline: 2px solid #000; outline-offset: 6px; }
.nh-v2 .nh-xp-desc {
  display: grid; grid-template-rows: 0fr;
  width: min(560px, calc(100vw - 240px));
  transition: grid-template-rows 0.7s cubic-bezier(0.25, 0.8, 0.3, 1);
}
.nh-v2 .nh-xp-desc-in { overflow: hidden; min-height: 0; }
.nh-v2 .is-open > * > .nh-xp-desc, .nh-v2 .is-open .nh-xp-desc { grid-template-rows: 1fr; }
.nh-v2 .nh-xp-desc ul { list-style: none; margin: 0; padding: 14px 0 6px; display: flex; flex-direction: column; gap: 10px; }
.nh-v2 .nh-xp-desc li {
  position: relative; padding-left: 16px; white-space: normal;
  font-family: "Inter", "Inter Placeholder", sans-serif; font-weight: 400;
  font-size: 16px; line-height: 1.45; letter-spacing: -0.02em; color: #000;
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
/* square bullets: the same 5px black squares as the menu icon */
.nh-v2 .nh-xp-desc li::before {
  content: ""; position: absolute; left: 0; top: calc(0.725em - 2.5px); width: 5px; height: 5px; background: #000;
}
.nh-v2 .is-open .nh-xp-desc li {
  opacity: 1; transform: none;
  transition: opacity 0.6s cubic-bezier(0, 0.56, 0.26, 0.97), transform 0.6s cubic-bezier(0, 0.56, 0.26, 0.97);
}
.nh-v2 .is-open .nh-xp-desc li:nth-child(1) { transition-delay: 0.12s; }
.nh-v2 .is-open .nh-xp-desc li:nth-child(2) { transition-delay: 0.22s; }
.nh-v2 .is-open .nh-xp-desc li:nth-child(3) { transition-delay: 0.32s; }
@media (max-width: 1199.98px) { .nh-v2 .nh-xp-desc { width: min(520px, calc(100vw - 200px)); } }
@media (max-width: 809.98px) {
  .nh-v2 .nh-xp-desc { width: 100%; }
  .nh-v2 .nh-xp-desc ul { padding-top: 10px; gap: 8px; }
  .nh-v2 .nh-xp-desc li { font-size: 14px; padding-left: 13px; }
}
/* pinning needs every ancestor to clip without becoming a scroll container */
@supports (overflow: clip) {
  .nh-v2 .nh-xp-pin, .nh-v2 .framer-QyeYm.framer-Dg6wz { overflow: clip !important; }
  .nh-v2 .nh-xp-pin { justify-content: flex-start !important; }
  .nh-v2 .nh-xp-pin > .framer-kscgcc { position: sticky !important; }
  .nh-v2 .nh-xp-track { flex: none; width: 100%; pointer-events: none; }
}

/* Spatia card: where the project grid has two columns, it spans both as a 16:9
   feature above the square cards (Nic: an odd number of squares looked uneven) */
@media (min-width: 810px) {
  .nh-feature-cell { grid-column: 1 / -1; }
  .nh-feature { aspect-ratio: 16 / 9; }
}
.nh-feature picture { display: contents; }

/* Hero on tall screens (e.g. a phone in desktop-site mode, 980 x 2000): Framer sizes it
   at 88% of the screen height between 810 and 1199px wide, which left ~1000px of
   empty white below the bio. Never taller than the screen is wide. */
@media (min-width: 810px) and (max-width: 1199.98px) {
  .nh-v2 .framer-c6378y { height: min(88vh, 84vw) !important; }
}
/* the grids give every row equal height (1fr); the feature row sets its own */
@media (min-width: 810px) {
  :is(.framer-pcf6c, .framer-193dvos):has(> .nh-feature-cell) { grid-auto-rows: auto !important; }
}

/* Experience timeline: rows align to the top so the line between logos stays put
   while a row opens; the black fill tracks scroll progress through each role */
.nh-v2 .nh-xp .framer-CGLio { align-items: flex-start !important; }
.nh-v2 .nh-xp-line { position: absolute; width: 1px; background: #d9d9d9; pointer-events: none; }
.nh-v2 .nh-xp-line > i { position: absolute; inset: 0; background: #000; transform: scaleY(0); transform-origin: top; }
