/* ===========================
   RESET & BASE
   =========================== */

/* ── Typed colour custom property — enables CSS to interpolate --accent
   between theme values so every var(--accent) use transitions automatically */
@property --accent {
  syntax:        '<color>';
  inherits:      true;
  initial-value: #0066FF;
}

html {
  scroll-behavior: smooth;
}

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --margin: 32px;                    /* fixed gutter — matches Figma exactly   */
  --pad:    clamp(32px, 4.27vw, 64px); /* section inner padding, scales w/ vp  */
  --nav-h:  72px;
  --accent: #0066FF;          /* theme colour — JS cycles this via setProperty */
  --bg:     #f9f9f9;

  /* Smooth theme transitions — JS overrides this inline during rapid cycling */
  transition: --accent 250ms ease;

  /* Grid column system — derived from the 12-col overlay grid
     --col  : width of one column (fluid, tracks viewport)
     --gut  : fixed gutter between columns = 20px
     Formula: (viewport − 2×margin − 2×pad − 11 gutters) ÷ 12            */
  --gut: 20px;
  --col: calc((100vw - 2 * (var(--margin) + var(--pad)) - 11 * var(--gut)) / 12);

  /* Header heights — change these and intro/footer overlaps update automatically */
  --header-h-top: 358px;   /* height of the top Tim_Kennedy header                */
  --header-h-bot: 358px;   /* height of the bottom Tim_Kennedy header             */
  --header-reveal-top: 20px;   /* how much extra of the top header peeks above the intro */
}

/* ── Pixel trail — squares follow cursor, snap to 8px grid, fade out ──────── */
.pixel-trail__dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 8px;
  height: 8px;
  background-color: var(--accent);
  pointer-events: none;
  z-index: 999998;
  will-change: transform, opacity;
}

/* ── Skill tooltip — grows from cursor square on skill hover ─────────────── */
.cursor-tooltip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999998;
  pointer-events: none;
  width: 300px;
  padding: 20px 24px;
  background-color: var(--accent);
  color: var(--bg);
  font-family: 'Space Mono', monospace;
  font-size: 13px;
  line-height: 1.65;
  transform-origin: center center;
  transform: translate(-50%, -50%) scale(0.05) rotate(0deg);
  opacity: 0;
  transition: transform 0.35s cubic-bezier(0.34, 1.4, 0.64, 1),
              opacity   0.2s  ease;
  will-change: transform, opacity;
}

.cursor-tooltip.is-active {
  transform: translate(-50%, -50%) scale(1) rotate(var(--tip-rotate, 4deg));
  opacity: 1;
}

/* Explicit reset for html + body to guarantee no gap above the navbar */
html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 400;
  color: var(--accent);
  background-color: var(--bg); /* solid block colour only — no grid */
}

a   { color: var(--accent); text-decoration: none; }
img { display: block; }

/* Explicitly restore system cursor — overrides any cached cursor:none
   from older deploys. Child elements (links, buttons) still inherit
   their own cursor values (pointer, grab, etc.) normally.           */
html { cursor: auto; }


/* ===========================
   LOADER
   =========================== */

.loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background-color: var(--bg);
  display: var(--loader-display, flex);
  align-items: center;
  justify-content: center;
  transition: opacity 0.5s ease;
}

.loader--hidden {
  opacity: 0;
  pointer-events: none;
}

.loader__text {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 40px;
  font-weight: 400;
  line-height: normal;
  letter-spacing: -0.8px;
  color: var(--accent);
  white-space: nowrap;
  user-select: none;
}


/* ===========================
   GRID REVEALER
   =========================== */

/* Full-screen cover that wipes top-to-bottom to reveal the grid */
.grid-revealer {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background-color: var(--bg);
  pointer-events: none;
  clip-path: inset(0 0 0 0);
}

body.page-ready .grid-revealer {
  /* Fast linear wipe = the wipe edge IS the "drawing line" for borders + grid */
  animation: grid-reveal 0.5s linear forwards;
}

@keyframes grid-reveal {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(100% 0 0 0); }
}


/* ===========================
   GRID OVERLAY
   =========================== */

/*
  Fixed 12-column design grid — visible over all page content.
  Columns: 12 | Type: stretch | Margin: 96px | Gutter: 20px
  Each column gets a 1px left + right stroke at 20% blue opacity.
  pointer-events: none so it never blocks interaction.
*/

.grid-overlay {
  position: fixed;
  inset: 0;
  /* top + bottom are set dynamically by JS to align exactly with the intro
     section's top edge and the sign-off section's bottom edge as you scroll. */
  z-index: 50;
  pointer-events: none;
  /* Match the content edge exactly: 32px section margin + fluid inner padding */
  padding: 0 calc(var(--margin) + var(--pad));
}

.grid-overlay__inner {
  height: 100%;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 20px;
}

.grid-overlay__col {
  border-left:  1px solid color-mix(in srgb, var(--accent) 10%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--accent) 10%, transparent);
}


/* ===========================
   PAGE INTRO ANIMATIONS
   =========================== */

/* Navbar always visible on the test page */
.navbar { opacity: 1; }

/*
  Two-phase reveal:
  ─────────────────────────────────────────────────────────────────────────────
  Phase 1 (0 → 500ms): grid-revealer wipes top-to-bottom at linear speed.
    The wipe edge acts as a "drawing cursor" — as it clears each section,
    only the structural borders + grid lines are visible because all inner
    content starts at opacity: 0. The borders live on container elements
    (not listed below), so they remain visible throughout.

  Phase 2 (500ms+): inner content fades up section by section, top-to-bottom,
    with 150ms stagger between sections.
  ─────────────────────────────────────────────────────────────────────────────
*/

/* Shared keyframes */
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0);   }
}
@keyframes reveal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── Default hidden state ──────────────────────────────────────────────────
   Only inner content hidden. Borders are on the parent containers and
   are NOT listed here — they stay visible during the Phase 1 wipe.       */

/* Header */
.t-header__name                               { opacity: 0; transform: translateY(8px); }

/* Hero (kept for case-study.html) */
.t-hero__slides                               { opacity: 0; }
.t-hero__labels                               { opacity: 0; transform: translateY(8px); }

/* Case study intro — first section below the hero */
.cs-intro__copy,
.cs-intro__role                               { opacity: 0; transform: translateY(8px); }

/* Intro */
.t-intro__copy > *                            { opacity: 0; transform: translateY(8px); }
.t-intro__globe                               { opacity: 0; }

/* Work */
.t-work__header                               { opacity: 0; transform: translateY(8px); }

/* About + Experience */
.t-about__header,
.t-about__copy,
.t-experience__header,
.t-experience__list                           { opacity: 0; transform: translateY(8px); }

/* Projects */
.t-projects__header,
.t-projects__grid                             { opacity: 0; transform: translateY(8px); }

/* Skills */
.t-skills__header,
.t-skills__right                              { opacity: 0; transform: translateY(8px); }

/* Sign-off */
.t-signoff__globe                             { opacity: 0; }
.t-signoff__copy > *                          { opacity: 0; transform: translateY(8px); }

/* Footer */
.t-footer__social,
.t-footer__credit                             { opacity: 0; transform: translateY(8px); }


/* ── Phase 2: staggered content reveal ────────────────────────────────────
   Delays start after the 500ms wipe, then stagger 150ms per section.    */

/* Header — first in viewport, starts as wipe clears.
   JS (animationend listener) removes this animation once it completes so
   the parallax script can reclaim the transform property.                */
body.page-ready .t-header__name {
  animation: reveal-up 0.8s ease-out forwards 0.5s;
}

/* Hero (kept for case-study.html) */
body.page-ready .t-hero__slides {
  animation: reveal-fade 0.6s ease-out forwards 0.5s;
}
body.page-ready .t-hero__labels {
  animation: reveal-up 0.6s ease-out forwards 0.65s;
}

/* Case study intro — steps in just after hero labels */
body.page-ready .cs-intro__copy { animation: reveal-up 0.6s ease-out forwards 0.8s; }
body.page-ready .cs-intro__role { animation: reveal-up 0.6s ease-out forwards 0.95s; }

/* Intro */
body.page-ready .t-intro__copy > * {
  animation: reveal-up 0.6s ease-out forwards 0.8s;
}
body.page-ready .t-intro__globe {
  animation: reveal-fade 0.6s ease-out forwards 0.85s;
}

/* Work */
body.page-ready .t-work__header {
  animation: reveal-up 0.6s ease-out forwards 0.95s;
}

/* About + Experience (same row, same delay) */
body.page-ready .t-about__header     { animation: reveal-up 0.6s ease-out forwards 1.1s; }
body.page-ready .t-about__copy       { animation: reveal-up 0.6s ease-out forwards 1.2s; }
body.page-ready .t-experience__header { animation: reveal-up 0.6s ease-out forwards 1.1s; }
body.page-ready .t-experience__list   { animation: reveal-up 0.6s ease-out forwards 1.25s; }

/* Projects */
body.page-ready .t-projects__header { animation: reveal-up 0.6s ease-out forwards 1.4s; }
body.page-ready .t-projects__grid   { animation: reveal-up 0.6s ease-out forwards 1.5s; }

/* Skills */
body.page-ready .t-skills__header { animation: reveal-up 0.6s ease-out forwards 1.65s; }
body.page-ready .t-skills__right  { animation: reveal-up 0.6s ease-out forwards 1.75s; }

/* Sign-off */
body.page-ready .t-signoff__globe    { animation: reveal-fade 0.6s ease-out forwards 1.9s; }
body.page-ready .t-signoff__copy > * { animation: reveal-up  0.6s ease-out forwards 1.95s; }
/* Override for the download link — fade only so the transform stays free for :hover */
body.page-ready .t-signoff__copy > .t-signoff__link { animation: reveal-fade 0.6s ease-out forwards 1.95s; }

/* Footer */
body.page-ready .t-footer__social { animation: reveal-up 0.5s ease-out forwards 2.05s; }
body.page-ready .t-footer__credit { animation: reveal-up 0.5s ease-out forwards 2.1s;  }


/* ===========================
   NAVBAR
   =========================== */

/*
  Three-part structure mirrors Figma exactly:
  [32px gutter | inner content | 32px gutter]

  The gutter divs carry the border-bottom only.
  The inner content carries border-bottom + border-left + border-right.
  This creates:
    • A continuous bottom border edge-to-edge
    • Vertical column lines at x=32 and x=viewport−32
  — the same vertical lines that the hero/section borders continue below.
*/

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--nav-h);
  display: flex;
  align-items: stretch;
  z-index: 100;
  background-color: var(--bg);
  transition: transform 0.45s ease;
}

.navbar--hidden {
  transform: translateY(-100%);
}

/* 32px gutters — bottom border only */
.navbar__gutter {
  flex: 0 0 var(--margin);
  border-bottom: 1px solid var(--accent);
}

/* Inner content — left + right + bottom borders */
.navbar__inner {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  border-left:   1px solid var(--accent);
  border-right:  1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
}

.navbar__name {
  font-family: 'Space Mono', monospace;
  font-size: clamp(21px, 2.2vw, 24px); /* 26px @ ~1500px viewport */
  font-weight: 500;
  letter-spacing: -3;
  line-height: normal;
  transition: opacity 0.35s ease;
}

.navbar__links {
  display: flex;
  align-items: center;
  gap: 8px;
}

.navbar__link {
  font-size: clamp(12px, 1.2vw, 18px); /* 18px @ ~1500px viewport */
  font-weight: 400;
  line-height: normal;
  padding: 24px 8px;
  cursor: pointer;
  transition: transform 0.25s ease;
  transform-origin: center;
}

.navbar__link:hover {
  text-decoration: underline;
  transform: scale(1.05) rotate(-2deg);
}

/* ── Colour toggle ───────────────────────────────────────────────────────────
   Rotation and pulse are driven entirely by JS (rAF lerp) so the speed
   eases smoothly between slow idle and fast active states.
   transform-origin on the img keeps the pivot at the icon centre.
*/
.navbar__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 8px;   /* matches .navbar__link vertical padding */
  background: none;
  border: none;
  cursor: pointer;
}

.navbar__toggle img {
  display: block;
  transform-origin: center;
}


/* ===========================
   INTRODUCTION SECTION
   =========================== */

/*
  Two-panel flex row within the 32px margins.
  Border strategy (avoids double-borders throughout):
    – Both panels: border-top NONE (hero bottom-border is the shared top line)
    – Copy panel:  border-right NONE (sphere left-border is the dividing line)
    – Sphere panel has full border-left/right/bottom → provides both the
      dividing line and the right outer column line.
*/

/* ── Parallax scroll-over ──────────────────────────────────────────────────
   All sections below the hero sit in a higher stacking layer (z-index: 2)
   so they slide up over the sticky hero as the user scrolls.
   background-color ensures full opaque coverage of the hero underneath.   */
/* Anchor scroll offset — keeps section tops flush with the navbar bottom */
.t-projects,
.t-about-row,
.t-work,
.t-skills {
  scroll-margin-top: var(--nav-h);
}

.t-intro,
.t-work,
.t-about-row,
.t-projects,
.t-skills,
.t-signoff,
.t-footer {
  position: relative;
  z-index: 2;
  background-color: var(--bg);
  /* Extend the background into the 32px side margin strips so sections
     visually cover the full width of the sticky footer (and top header)
     as they scroll over it — prevents border bleeding through the gaps.
     Two offset shadows (no spread) fill only left/right, not top/bottom,
     so section borders at the top and bottom edges are unaffected.       */
  box-shadow:
    calc(-1 * var(--margin)) 0 0 0 var(--bg),
    var(--margin)            0 0 0 var(--bg);
}

.t-intro {
  display: flex;
  align-items: stretch;
  /* Padding instead of margin so background-color covers the full viewport
     width — prevents the sticky header grid from bleeding through the sides */
  padding-left:  var(--margin);
  padding-right: var(--margin);
  /* Pull the intro up by half the header height so it overlays the bottom 50%
     of the top header on load. The intro's ::before border-top (edge-to-edge)
     creates the dividing line cutting through the middle of the name text.    */
  margin-top: calc(-1 * var(--header-h-top) / 2 + clamp(7px, 1.4vw, 18px));
}

/* Full-viewport-width top stroke — element is now full-width so no offset needed */
.t-intro::before {
  content: '';
  position: absolute;
  top: 0;
  left:  0;
  right: 0;
  border-top: 1px solid var(--accent);
}

/* ── Left: copy — 9 columns ── */
.t-intro__copy {
  flex: 0 0 calc(var(--pad) + 9 * var(--col) + 8 * var(--gut));
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-left:   1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  /* border-top: none  — hero bottom is the top line */
  /* border-right: none — sphere left is the divider  */
}

.t-intro__text--large {
  font-size: clamp(20px, 2.47vw, 34px); /* 37px @ ~1500px viewport */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  margin-bottom: 40px;
  
  
}

.t-intro__link {
  color: var(--accent);
  transition: transform 0.25s ease;
  transform-origin: center;
  display: inline-block;
}

.t-intro__link:hover {
  text-decoration: underline;
  transform: scale(1.03) rotate(-1deg);
}

.t-intro__text--small {
  font-size: clamp(12px, 1.2vw, 18px); /* 18px @ ~1500px viewport */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

/* ── Right: sphere — fills remaining 3 columns ── */
.t-intro__sphere {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border: 1px solid var(--accent);
  border-top: none; /* hero bottom is the top line */
}

.t-intro__globe {
  display: block;
  /* Scale down gracefully if the panel is narrower than 234px */
  width:  min(234px, calc(100% - 16px));
  height: min(234px, calc(100% - 16px));
  aspect-ratio: 1;
  flex-shrink: 0;
}


/* ===========================
   HEADER SECTION (TOP + BOTTOM)
   =========================== */

/*
  Full-viewport-width header component — appears at the top of the page
  (replacing the hero) and again between the skills and sign-off sections.

  Structure:
    .t-header               — shared base (307px, full-width, overflow hidden)
    .t-header--top          — sticky below navbar, z-index 1 (intro slides over it)
    .t-header--bottom       — sticky at nav height, z-index 1 (sign-off slides over it)
    .t-header__grid         — dashed SVG grid background (top 2px, 174px tall)
    .t-header__name         — 172px "Tim_Kennedy" name text, centered
*/

.t-header {
  position: relative;
  width: 100%;
  height: var(--header-h-top);
  overflow: hidden;
  background-color: var(--bg);
  /* No border — the section dividers come from the intro's ::before (top header)
     and the footer's border-top (bottom header), both cutting at the 50% mark. */
  /* Flexbox centres the name text vertically so it sits at the midpoint of the
     header at every viewport width — the intro and footer always cut through the
     exact centre of the text regardless of how small the font clamps down to.   */
  display: flex;
  align-items: center;
}

.t-header--top {
  position: sticky;
  top: var(--nav-h);
  z-index: 1;
  margin-top: var(--nav-h); /* push natural position below fixed navbar */
}

.t-header--bottom {
  /* Not sticky — sits in normal flow between sign-off and footer.
     z-index 1 so footer (z-index 2) renders on top and covers the bottom half. */
  position: relative;
  z-index: 1;
  height: var(--header-h-bot);
}

/* Dashed grid background — sits behind the name text.
   Inset by --margin on each side so it only occupies the same horizontal
   band as the content sections; the 32px side strips stay plain --bg,
   preventing the grid from showing through section margins on scroll. */
.t-header__grid {
  position: absolute;
  top: 0;
  left: var(--margin);
  right: var(--margin);
  bottom: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M 20 0 L 0 0 0 20' fill='none' stroke='%230066FF' stroke-width='0.5' stroke-dasharray='2 2'/%3E%3C/svg%3E");
  background-size: 24px 24px;
  background-repeat: repeat;
  opacity: 0.40;
  pointer-events: none;
}

/* Large name — vertically centred by parent flexbox, scales with viewport */
.t-header__name {
  /* position: relative (flex child) — NOT absolute.
     top/left/right removed: vertical position is owned by parent align-items: center
     so the text centre always coincides with the header midpoint.
     At every viewport width the intro (top) and footer (bottom) cut through the
     exact vertical centre of this text, keeping the overlay consistent.         */
  width: 100%;
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(48px, 11.5vw, 172px);
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.02em; /* ≈ -3.44px at 172px */
  text-align: center;
  line-height: 1;
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
  will-change: transform;
}


/* ===========================
   HERO SLIDESHOW
   =========================== */

/*
  The hero sits within the same 32px margins as the navbar inner content,
  so its left and right borders are the same vertical column lines.
  border-top is omitted — the navbar's border-bottom IS the hero's top edge.
*/

.t-hero {
  position: sticky;          /* pins in place while content below scrolls over */
  top: var(--nav-h);         /* sticks flush below the fixed navbar             */
  z-index: 1;                /* sits behind the overlay sections                */
  margin: 0 var(--margin);
  margin-top: var(--nav-h);  /* pushes hero to correct natural position on load */
  height: 650px;
  overflow: hidden;
  background-color: var(--bg);
  border-left:   1px solid var(--accent);
  border-right:  1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  /* no border-top — navbar bottom border serves as the top line */
}

/* ── Slides ── */
.t-hero__slides {
  position: absolute;
  inset: 0;
}

.t-hero__slide {
  position: absolute;
  inset: 0;
  visibility: hidden;
}

.t-hero__slide.is-active {
  visibility: visible;
}

.t-hero__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
  user-select: none;
}

/* ── Corner labels ── */
.t-hero__labels {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--pad);
  pointer-events: none;
  z-index: 2;
}

.t-hero__labels-top,
.t-hero__labels-bottom {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.t-hero__label {
  font-size: clamp(12px, 1.2vw, 18px); /* 18px @ ~1500px viewport */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

.t-hero__label--star {
  font-size: clamp(18px, 1.93vw, 29px); /* 29px @ ~1500px viewport */
  line-height: 1;
}


/* ===========================
   WORK SECTION
   =========================== */

.t-work {
  position: relative;
  margin: 0 var(--margin);
  margin-top: -1px;
  border: 1px solid var(--accent);
  min-height: 700px;
  overflow: hidden;
  background-color: var(--bg);
}

/* Items start hidden; physics positions and reveals them */
.t-work__item {
  width: 218px;
  height: 218px;
  cursor: pointer;
  flex-shrink: 0;
  opacity: 0;
}

.t-work__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Header row — spans full width, "Work ↓" left / "Select an image" right */
.t-work__header {
  position: absolute;
  top: var(--pad);
  left: var(--pad);
  right: var(--pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: clamp(16px, 1.6vw, 24px);
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  z-index: 3;
  pointer-events: none;
  user-select: none;
}

.t-work__header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Reusable bouncing ↓ arrow — used across all section headers */
.t-arrow {
  display: inline-block;
  animation: arrow-bounce 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

@keyframes arrow-bounce {
  0%, 100% { transform: translateY(0);   }
  50%       { transform: translateY(6px); }
}

/* ── Case study navbar back link ── */
.cs-nav-home {
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: inherit;
}

.cs-nav-arrow {
  font-family: 'Space Mono', monospace;
  display: inline-block;
  animation: arrow-bounce-left 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  line-height: 1;
  font-size: 1.7vw;
}

@keyframes arrow-bounce-left {
  0%, 100% { transform: translateX(0);    }
  50%       { transform: translateX(-6px); }
}


.t-work__select-label {
  font-size: clamp(12px, 1.2vw, 18px);
}


/* ===========================
   ABOUT + EXPERIENCE SECTION
   =========================== */

.t-about-row {
  display: flex;
  align-items: stretch;
  margin: 0 var(--margin);
  margin-top: -1px;
  border-top: 1px solid var(--accent);
}

/* About panel — 8 columns */
.t-about {
  flex: 0 0 calc(var(--pad) + 8 * var(--col) + 7 * var(--gut));
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: var(--pad);
  border-left:   1px solid var(--accent);
  border-right:  1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  background-color: var(--bg);
}

/* Experience panel — fills remaining 34.75% */
.t-experience {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: var(--pad);
  border-right:  1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  /* border-left: none — .t-about right border is the shared divider */
  background-color: var(--bg);
}

/* Section headers */
.t-about__header,
.t-experience__header {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  font-size: clamp(16px, 1.6vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  white-space: nowrap;
}

/* About body copy */
.t-about__copy {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.t-about__text--large {
  font-size: clamp(18px, 1.9vw, 40px); /* 32px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);

}

.t-about__text--medium {
  font-size: clamp(14px, 1.5vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

/* Experience list */
.t-experience__list {
  display: flex;
  flex-direction: column;
}

/* Cards: pb only for first, py for middle, pt only for last */
.t-experience__card {
  padding: 24px 0;
}

.t-experience__card--first {
  padding-top: 0;
}

.t-experience__card--last {
  padding-bottom: 0;
}

.t-experience__card > * {
  display: block;
}

.t-experience__date {
  font-size: clamp(13px, 1.33vw, 18px); /* 20px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  opacity: 50%;
  margin-bottom: 8px;
}

.t-experience__company {
  font-size: clamp(15px, 1.73vw, 26px); /* 26px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  margin-bottom: 8px;
}

.t-experience__role {
  font-size: clamp(13px, 1.33vw, 20px); /* 20px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}


/* ===========================
   PERSONAL PROJECTS SECTION
   =========================== */

.t-projects {
  margin: 0 var(--margin);
  margin-top: -1px;
  border: 1px solid var(--accent);
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  gap: 40px;
  background-color: var(--bg);
}

.t-projects__header {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  font-size: clamp(16px, 1.6vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  white-space: nowrap;
}

.t-projects__grid {
  display: flex;
  gap: var(--pad);      /* 64px @ ~1500px — matches Figma gap-[64px] */
  align-items: flex-start;
  width: 100%;
}

.t-projects__image {
  flex: 1 0 0;
  height: 450px;        /* Figma: h-[450px] */
  min-width: 1px;
  position: relative;
  overflow: hidden;
  transition: transform 0.25s ease;
  transform-origin: center;
}

.t-projects__image:hover {
  transform: scale(1.05) rotate(-2deg);
}

.t-projects__image a {
  position: absolute;
  inset: 0;
  display: block;
}

.t-projects__image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}


/* ===========================
   SKILLS SECTION
   =========================== */

.t-skills {
  margin: 0 var(--margin);
  margin-top: -1px;
  border: 1px solid var(--accent);
  padding: var(--pad);
  background-color: var(--bg);
  overflow: hidden;
}

.t-skills__inner {
  display: flex;
  gap: clamp(20px, 2vw, 40px); /* minimum breathing room — right panel drives alignment */
  align-items: flex-start;
  width: 100%;
}

.t-skills__header {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  font-size: clamp(16px, 1.6vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  white-space: nowrap;
  flex-shrink: 0;
}

.t-skills__right {
  flex: 0 0 calc(9 * var(--col) + 8 * var(--gut)); /* exactly 9 grid columns */
  margin-left: auto; /* right-align to the grid edge — gap between header adjusts automatically */
  display: flex;
  flex-direction: column;
  gap: 32px;
  min-width: 0;
}

.t-skills__intro {
  font-size: clamp(18px, 2.13vw, 40px); /* 32px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  
}

.t-skills__list {
  display: flex;
  gap: 20px;            /* Figma: gap-[20px] */
  align-items: flex-start;
  width: 100%;
}

.t-skills__col {
  flex: 1 0 0;
  display: flex;
  flex-direction: column;
  gap: 32px;            /* Figma: gap-[32px] between skills */
  min-width: 0;
}

.t-skills__skill {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 24px 0;      /* Figma: py-[24px] */
  border-bottom: 1px dashed var(--accent);
  font-size: clamp(13px, 1.33vw, 20px); /* 20px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  background-color: var(--bg);
}


/* ===========================
   SIGN-OFF SECTION
   =========================== */

/*
  Two-panel flex row — mirrors the intro section structure.
  Left sphere panel: fixed 384px width, full border.
  Right copy panel: flex-1, full border, border-left removed (sphere right is the divider).
  margin-top: -1px collapses with the skills section bottom border.
*/

.t-signoff {
  display: flex;
  align-items: stretch;
  margin: 0 var(--margin);
  margin-top: -1px;
}

/* Full-viewport-width bottom stroke — mirrors .t-intro::before at the top */
.t-signoff::after {
  content: '';
  position: absolute;
  bottom: 0;
  left:  calc(-1 * var(--margin));
  right: calc(-1 * var(--margin));
  border-bottom: 1px solid var(--accent);
}

/* ── Left: sphere — fills remaining 3 columns ── */
.t-signoff__sphere {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border: 1px solid var(--accent);
  background-color: var(--bg);
}

.t-signoff__globe {
  display: block;
  width:  min(186px, calc(100% - 16px));
  height: min(186px, calc(100% - 16px));
  aspect-ratio: 1;
  flex-shrink: 0;
}

/* ── Right: copy — 9 columns ── */
.t-signoff__copy {
  flex: 0 0 calc(var(--pad) + 9 * var(--col) + 8 * var(--gut));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 40px;
  padding: var(--pad);
  border: 1px solid var(--accent);
  border-left: none; /* sphere right border is the shared divider */
  background-color: var(--bg);
}

.t-signoff__tagline {
  font-size: clamp(14px, 1.6vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

.t-signoff__title {
  font-size: clamp(20px, 2.53vw, 38px); /* 38px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

.t-signoff__link {
  font-size: clamp(14px, 1.6vw, 24px); /* 24px @ ~1500px */
  font-weight: 400;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  display: inline-block;
  transition: transform 0.25s ease;
  transform-origin: left center;
  transform: none; /* explicit base so :hover can override after animation clears */
}

.t-signoff__link:hover {
  text-decoration: underline;
  transform: scale(1.05) rotate(-2deg);
}


/* ===========================
   PAGE END WRAPPER
   =========================== */

/*
  Sticky bottom container — mirrors the top header mechanism.
  Sticks at viewport bottom (z-index 1) so the sign-off (z-index 2) can
  slide over it as the user scrolls, then reveal it when the sign-off
  scrolls fully away.
  overflow: hidden clips any content that escapes below the footer edge.
*/
.t-page-end {
  position: sticky;
  bottom: 0;
  z-index: 1;
  overflow: hidden;
}


/* ===========================
   FOOTER
   =========================== */

/*
  Three-part structure — mirrors the navbar exactly, but uses border-top
  instead of border-bottom (the sign-off bottom border serves as the shared edge).
  [32px gutter | inner content | 32px gutter]
*/

.t-footer {
  display: flex;
  align-items: stretch;
  height: var(--nav-h); /* 72px — same height as navbar */
  /* Pull footer up by half the bottom header height so its border-top cuts
     through the middle of the bottom header's Tim_Kennedy name text.        */
  margin-top: calc(-1 * var(--header-h-bot) / 2 + -0.6vw);
  
}

/* 32px gutters — top border only */
.t-footer__gutter {
  flex: 0 0 var(--margin);
  border-top: 1px solid var(--accent);
}

/* Inner content — left + right + top borders */
.t-footer__inner {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  border-top:   1px solid var(--accent);
  border-left:  1px solid var(--accent);
  border-right: 1px solid var(--accent);
  background-color: var(--bg);
}

.t-footer__social {
  font-size: clamp(13px, 1.33vw, 20px); /* 20px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}

.t-footer__social-link {
  color: var(--accent);
  text-decoration: none;
  display: inline-block;
  transform-origin: center;
  transition: transform 0.25s ease;
}

.t-footer__social-link:hover {
  text-decoration: underline;
  transform: scale(1.05) rotate(-2deg);
}

.t-footer__credit {
  font-size: clamp(12px, 1.27vw, 19px); /* 19px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}




/* ===========================
   CASE STUDY PAGES
   =========================== */

/* Experience list */
.t-role__list {
  display: flex;
  flex-direction: column;
}

/* Cards: pb only for first, py for middle, pt only for last */
.t-role__card {
  padding: 40px 0;
  border-bottom: rgb(0, 102, 255, 0.07);
  border-bottom-width: 1px;
  border-bottom-style: dashed;
}

.t-role__card--first {
  padding-top: 0;
}

.t-role__card--last {
  padding-bottom: 0;
}

.t-role__card > * {
  display: block;
}


.t-role__role {
  font-size: clamp(13px, 1.33vw, 20px); /* 20px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
}


/* Copy */

.t-copy__intro {
  font-size: clamp(16px, 2.13vw, 24px); /* 32px @ ~1500px */
  font-weight: 400;
  line-height: normal;
  color: var(--accent);
  
}

/* ===========================
   RESPONSIVE — < 1000px
   =========================== */

@media (max-width: 999px) {

  /* ── Header heights: smaller on mobile ─────────────────────────────────── */
  :root {
    --header-h-top: 250px;
    --header-h-bot: 250px;
  }

  /* ── Header grid: extend to full viewport width ────────────────────────── */
  .t-header__grid {
    left: 0;
    right: 0;
  }

  /* ── Intro: hide globe, copy spans full width ──────────────────────────── */
  .t-intro__sphere {
    display: none;
  }

  .t-intro__copy {
    flex: 1 1 auto;
    border-right: 1px solid var(--accent);
  }

  /* ── Case Studies: images stack vertically, 40px gap ──────────────────── */
  .t-projects__grid {
    flex-direction: column;
    gap: 40px;
  }

  .t-projects__image {
    flex: none;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
  }

  /* ── About + Experience: stack vertically ──────────────────────────────── */
  .t-about-row {
    flex-direction: column;
  }

  .t-about {
    flex: none;
  }

  .t-experience {
    border-left:  1px solid var(--accent); /* was relying on .t-about right border */
    border-top:   none;                    /* .t-about bottom border is the shared edge */
  }

  /* ── Work Archive: static 2-column grid, no physics ───────────────────── */
  .t-work {
    min-height: auto;
    display: flex;
    flex-direction: column;
    gap: var(--pad);
    padding: var(--pad);
    overflow: hidden;
  }

  .t-work__header {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    padding: 0;
  }

  .t-work__select-label {
    display: none; /* instruction only relevant for physics interaction */
  }

  /* desktop: wrapper is a zero-height block (all children are absolute) */
  /* mobile:  wrapper becomes the 2-col grid with 40px gutters            */
  .t-work__items {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
  }

  .t-work__item {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    opacity: 1;
    cursor: default;
    border: none;
  }

  /* ── Skills: header top-left, content full width below ─────────────────── */
  .t-skills__inner {
    flex-direction: column;
    gap: 32px;
  }

  .t-skills__right {
    flex: none;
    width: 100%;
    margin-left: 0;
  }

  .t-skills__list {
    flex-direction: column;
    gap: 0;
    width: 100%;
  }

  .t-skills__col {
    flex: none;      /* override flex: 1 0 0 so width is driven by parent stretch */
    width: 100%;
    gap: 0;          /* border-bottom + padding on each item handles separation   */
  }

  /* ── Sign-off: hide globe, copy spans full width ───────────────────────── */
  .t-signoff__sphere {
    display: none;
  }

  .t-signoff__copy {
    flex: 1 1 auto;
    border-left: 1px solid var(--accent); /* was none — sphere right was the divider */
  }

  /* ── Font sizes: +1vw on every content text element ────────────────────────
     At < 1000px the vw values in the desktop clamps are too small, so each
     viewport-relative value is nudged up by 1vw to keep text readable.       */

  .t-intro__text--large       { font-size: clamp(20px, 3.47vw, 34px); }
  .t-intro__text--small       { font-size: clamp(12px, 2.2vw,  18px); }

  .t-projects__header         { font-size: clamp(16px, 2.6vw,  24px); }

  .t-about__header,
  .t-experience__header       { font-size: clamp(16px, 2.6vw,  24px); }
  .t-about__text--large       { font-size: clamp(18px, 3.13vw, 40px); }
  .t-about__text--medium      { font-size: clamp(14px, 2.6vw,  24px); }

  .t-experience__date         { font-size: clamp(13px, 2.33vw, 20px); }
  .t-experience__company      { font-size: clamp(15px, 2.73vw, 26px); }
  .t-experience__role         { font-size: clamp(13px, 2.33vw, 20px); }

  .t-work__header             { font-size: clamp(16px, 2.6vw,  24px); }

  .t-skills__header           { font-size: clamp(16px, 2.6vw,  24px); }
  .t-skills__intro            { font-size: clamp(18px, 3.13vw, 40px); }
  .t-skills__skill            { font-size: clamp(13px, 2.33vw, 20px); }

  .t-signoff__tagline         { font-size: clamp(14px, 2.6vw,  24px); }
  .t-signoff__title           { font-size: clamp(20px, 3.53vw, 38px); }
  .t-signoff__link            { font-size: clamp(14px, 2.6vw,  24px); }

  .t-footer__social           { font-size: clamp(13px, 2.33vw, 20px); }
  .t-footer__credit           { font-size: clamp(12px, 2.27vw, 19px); }

}


/* ===========================
   RESPONSIVE — < 600px
   =========================== */

@media (max-width: 599px) {

  /* ── Remove side margins — sections stretch edge to edge ───────────────────
     Setting --margin: 0 propagates through every rule that uses it:
     section margins, intro/signoff padding, navbar gutters, box-shadows.    */
  :root {
    --margin:       0px;
    --pad:          32px;
    --nav-h:        60px;
    --header-h-top: 150px;
    --header-h-bot: 150px;
  }

  /* ── Navbar: 16px side padding, name + colour wheel only, hide nav links ── */
  .navbar__inner {
    padding: 0 16px;
  }

  .navbar__link {
    display: none;
  }

  /* ── Footer: hide credit, centre social links ───────────────────────────── */
  .t-footer__credit {
    display: none;
  }

  .t-footer__inner {
    justify-content: center;
  }

  /* ── Work Archive: single column, gap matches container padding ────────── */
  /* ── Work archive: 5/6-wide items alternating left/right ───────────────── */
  .t-work__items {
    grid-template-columns: repeat(6, 1fr);
    gap: 24px;
  }

  .t-work__item {
    border: none;
    grid-column: 1 / 6; /* 5 cols wide, left-aligned */
  }

  .t-work__item:nth-child(even) {
    grid-column: 2 / 7; /* 5 cols wide, right-aligned */
  }

  /* ── Grid overlay: 6 columns at phone widths ───────────────────────────── */
  .grid-overlay {
    overflow: hidden; /* clips the second row that 12 items create in a 6-col grid */
  }

  .grid-overlay__inner {
    grid-template-columns: repeat(6, 1fr);
  }

  /* ── Bottom header: hidden at phone widths — footer nav is enough ──────── */
  .t-header--bottom           { display: none; }

  /* Reset footer margin — no bottom header to overlap at this breakpoint */
  .t-footer                   { margin-top: 0; }

  /* ── Header name: larger at phone width ─────────────────────────────────── */
  .t-header__name             { font-size: 14vw; }

  /* ── Section vertical padding: 48px top/bottom (left/right stay at --pad) ─
     Covers: intro copy, selected work, about, experience, work archive
     header, skills, and signoff copy panels.                                 */
  .t-intro__copy,
  .t-projects,
  .t-about,
  .t-experience,
  .t-work,
  .t-skills,
  .t-signoff__copy            { padding-top: 48px; padding-bottom: 48px; }

  /* ── Font sizes: +1.5vw on top of the 1000px bump (+0.5 more here) ─────── */
  .t-intro__text--large       { font-size: 7vw; }
  .t-intro__text--small       { font-size: clamp(12px, 4.45vw, 18px); }

  .t-projects__header         { font-size: clamp(16px, 4.85vw, 24px); }

  .t-about__header,
  .t-experience__header       { font-size: clamp(16px, 4.85vw, 24px); }
  .t-about__text--large,
  .t-about__text--medium      { font-size: clamp(18px, 5.38vw, 40px); }

  .t-experience__date         { font-size: clamp(13px, 4.58vw, 20px); }
  .t-experience__company      { font-size: clamp(15px, 4.98vw, 26px); }
  .t-experience__role         { font-size: clamp(13px, 4.58vw, 20px); }

  .t-work__header             { font-size: clamp(16px, 4.85vw, 24px); }

  .t-skills__header           { font-size: clamp(16px, 4.85vw, 24px); }
  .t-skills__intro            { font-size: clamp(18px, 5.38vw, 40px); }
  .t-skills__skill            { font-size: clamp(13px, 4.58vw, 20px); }

  .t-signoff__tagline         { font-size: clamp(14px, 4.85vw, 24px); }
  .t-signoff__title           { font-size: clamp(20px, 5.78vw, 38px); }
  .t-signoff__link            { font-size: clamp(14px, 4.85vw, 24px); }

  .t-footer__social           { font-size: clamp(13px, 4.58vw, 20px); }
  .t-footer__credit           { font-size: clamp(12px, 4.52vw, 19px); }

}
