/* =========================================================
   Nynne Surel — Portfolio
   Shared styles
   ---------------------------------------------------------
   Grid system
     Desktop  (≥1280)  : 12 cols, 20px gutter, 20px margin
     Tablet   (800–1279): 8 cols, 20px gutter, 20px margin
     Mobile   (1–799)  : 6 cols, 15px gutter, 15px margin
   ========================================================= */

/* ---------- Custom font: Delight SemiBold ----------
   The single weight (SemiBold) covers the whole site; size
   creates hierarchy. The font-weight range claims any
   requested weight so existing rules never trigger faux-bold.
*/
@font-face {
  font-family: "Delight";
  src: url("fonts/Delight-SemiBold.woff2") format("woff2"),
       url("fonts/Delight-SemiBold.ttf")  format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, p, ul, ol, figure { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button {
  font: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; color: inherit;
}




/* ---------- Tokens ---------- */
:root {
  /* Color — light mode (default) */
  --color-bg: #ffffff;
  --color-ink: #000000;
  --color-muted: #E3E1E1;
  --color-line: #E3E1E1;
  --color-placeholder: #E3E1E1;
  --color-placeholder-2: #E3E1E1;
  --color-overlay: rgba(255, 255, 255, .85);

  /* Type */
  --font-sans: "Delight", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --fs-h1: 40px; --lh-h1: 42px;
  --fs-h2: 34px; --lh-h2: 36px;
  --fs-h3: 20px; --lh-h3: 22px;
  --fs-b1: 16px; --lh-b1: 17.5px;
  --fs-b2: 12px; --lh-b2: 13.5px;

  /* Grid — desktop defaults (≥1280) */
  --cols: 12;
  --gutter: 20px;
  --margin: 20px;

  /* Layout */
  --radius-pill: 999px;

  color-scheme: light;
}

/* Dark mode — set on <html data-theme="dark"> */
[data-theme="dark"] {
  --color-bg: #000000;
  --color-ink: #ffffff;
  --color-muted: #3C3C3C;
  --color-line: #3C3C3C;
  --color-placeholder: #3C3C3C;
  --color-placeholder-2: #3C3C3C;
  --color-overlay: rgba(14, 14, 14, .85);
  color-scheme: dark;
}

/* Smooth theme transitions on color-bearing properties only */
body, .work-card__caption, .nav__link, .nav__toggle, .project-row figure,
.project-hero, .about-portrait, .work-card {
  transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

/* Tablet 800–1279 */
@media (max-width: 1279px) {
  :root {
    --cols: 8;
    --gutter: 20px;
    --margin: 20px;
  }
}

/* Mobile 1–799 */
@media (max-width: 799px) {
  :root {
    --cols: 6;
    --gutter: 15px;
    --margin: 15px;

    --fs-h1: 28px; --lh-h1: 32px;
    --fs-b1: 12px; --lh-b1: 13.5px;
  }
}

/* ---------- Base ---------- */
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body {
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-b1);
  line-height: var(--lh-b1);
  font-weight: 500;        /* Delight Medium */
  font-synthesis: none;    /* never fake bold/italic */
  letter-spacing: -0.005em;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* main expands to fill the column so the footer sticks
   to the bottom of the viewport on short pages.            */
main { flex: 1; }

/* ---------- Type utilities ---------- */
.h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: 500; letter-spacing: -0.015em; }
.h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: 500; letter-spacing: -0.01em; }
.h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: 600; letter-spacing: -0.005em; }
.b1 { font-size: var(--fs-b1); line-height: var(--lh-b1); }
.b2 { font-size: var(--fs-b2); line-height: var(--lh-b2); }
.muted { color: var(--color-muted); }

/* ---------- Grid ----------------------------------------
   .grid     : page-level grid. Full viewport width, side
               margins, gutters between columns.
   .subgrid  : nested grid that inherits the parent's track
               sizing — children align perfectly to the page
               grid (modern browser support).
   .span-N   : children span N columns (responsive utilities
               below adjust spans per breakpoint).
   --------------------------------------------------------- */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  column-gap: var(--gutter);
  padding-left: var(--margin);
  padding-right: var(--margin);
  width: 100%;
}

.subgrid {
  display: grid;
  grid-template-columns: subgrid;
  column-gap: var(--gutter);
}

/* Span utilities — desktop (12-col) */
.span-1  { grid-column: span 1; }
.span-2  { grid-column: span 2; }
.span-3  { grid-column: span 3; }
.span-4  { grid-column: span 4; }
.span-5  { grid-column: span 5; }
.span-6  { grid-column: span 6; }
.span-7  { grid-column: span 7; }
.span-8  { grid-column: span 8; }
.span-9  { grid-column: span 9; }
.span-10 { grid-column: span 10; }
.span-11 { grid-column: span 11; }
.span-12 { grid-column: span 12; }

/* Tablet — clamp spans to 8 */
@media (max-width: 1279px) {
  .span-9, .span-10, .span-11, .span-12 { grid-column: span 8; }
  .span-md-1  { grid-column: span 1; }
  .span-md-2  { grid-column: span 2; }
  .span-md-3  { grid-column: span 3; }
  .span-md-4  { grid-column: span 4; }
  .span-md-5  { grid-column: span 5; }
  .span-md-6  { grid-column: span 6; }
  .span-md-7  { grid-column: span 7; }
  .span-md-8  { grid-column: span 8; }
}

/* Mobile — clamp spans to 6 */
@media (max-width: 799px) {
  .span-7, .span-8, .span-9, .span-10, .span-11, .span-12 { grid-column: span 6; }
  .span-sm-1 { grid-column: span 1; }
  .span-sm-2 { grid-column: span 2; }
  .span-sm-3 { grid-column: span 3; }
  .span-sm-4 { grid-column: span 4; }
  .span-sm-5 { grid-column: span 5; }
  .span-sm-6 { grid-column: span 6; }
}

/* Vertical rhythm spacers for grid children */
.row-gap-sm > * { margin-bottom: 0; }
.section-pad   { padding-block: 56px; }
.section-pad-sm{ padding-block: 28px; }

/* ---------- Top navigation ----------
   Each item placed by explicit grid-column on the page grid:
     col 1               brand    "nynne surel"
     cols 3 / 4 / 5      links    work · about · connect
     last col            toggle   sun ↔ moon (10×10)
   Type is fixed at 12px on every breakpoint.                 */
.nav-row {
  align-items: center;
  padding-top: 20px;
  padding-bottom: 20px;
}
.nav__brand,
.nav__link {
  font-size: 12px;
  line-height: 1;
  align-self: center;
  white-space: nowrap;
}
.nav__link {
  display: inline-block;
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  color: var(--color-ink);
  transition: border-color .15s ease;
}
.nav__link:hover,
.nav__link[aria-current="page"] {
  border-color: var(--color-ink);
}

.nav__brand {
  grid-column: 1;
  font-weight: 500;
  letter-spacing: -0.005em;
  justify-self: start;
  position: relative;       /* anchor for hover dots */
}

/* Brand hover: text swaps to 10 dots — one dot per letter of
   "nynne surel". Dot size + spacing roughly match the width
   and rhythm of the actual letters at 12px Delight SemiBold,
   so the row replaces the text without growing the layout.    */
.nav__brand__text {
  display: inline-block;
  transition: opacity .15s ease;
}
.nav__brand__dots {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 0;                   /* dots touch within each group */
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
}
.nav__brand__dots > span {
  width: 6px;               /* ~one letter wide */
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.nav__brand__dots > span:nth-child(6) {
  margin-left: 4px;         /* gap between the two groups */
}
.nav__brand:hover .nav__brand__text { opacity: 0; }
.nav__brand:hover .nav__brand__dots { opacity: 1; }

/* Menu container — spans 2 columns on desktop & tablet.
   Internally divided into two sub-cells with the same gutter
   as the page grid, so:
     · work + about sit in the first sub-cell (= col 3),
       right-aligned so "about" hits the col-3 right edge;
     · connect occupies the second sub-cell (= col 4),
       left-aligned (justify-self: start) so the pill is sized
       to its text and not stretched to fill the cell.
   With the pair gap matching the page gutter, all three items
   end up with the same horizontal spacing.                     */
.nav__menu {
  grid-column: 3 / span 2;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--gutter);
  align-items: center;
  align-self: center;
}
/* Connect is a plain nav__link again (dropdown removed). */
.nav__menu > .nav__link {
  justify-self: start;
  margin-left: -8px;
}
.nav__menu__pair {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  justify-self: end;
  margin-right: 8px;
}

/* ---------- Right side of nav: socials + toggle ---------- */
.nav__right {
  grid-column: -2 / -1;
  display: flex;
  align-items: center;
  justify-self: end;
}
.nav__social { display: none; }
@media (min-width: 1280px) {
  .nav__right {
    grid-column: 11 / -1;
    gap: var(--gutter);
    justify-self: stretch;
  }
  .nav__right .nav__toggle { margin-left: auto; }
  .nav__social {
    display: inline-block;
    font-size: 12px;
    line-height: 1;
    color: var(--color-muted);
    transition: color .15s ease;
    white-space: nowrap;
  }S
  .nav__social:hover,
  .nav__social:focus-visible {
    color: var(--color-ink);
    outline: none;
  }
}

/* Line-by-line reveal — same fade/lift as the intro dots,
   staggered so each line appears 200 ms after the last. */
@keyframes line-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.about-hero .line,
.project-body__text .line,
.connect__list li {
  display: block;
  opacity: 0;
  animation: line-in 0.6s cubic-bezier(.2, .7, .2, 1) forwards;
}

.about-hero .line:nth-child(1),
.project-body__text .line:nth-child(1),
.connect__list li:nth-child(1) { animation-delay: 0.1s; }

.about-hero .line:nth-child(2),
.project-body__text .line:nth-child(2),
.connect__list li:nth-child(2) { animation-delay: 0.3s; }

.about-hero .line:nth-child(3),
.project-body__text .line:nth-child(3),
.connect__list li:nth-child(3) { animation-delay: 0.5s; }

.about-hero .line:nth-child(4),
.project-body__text .line:nth-child(4),
.connect__list li:nth-child(4) { animation-delay: 0.7s; }

.about-hero .line:nth-child(5),
.project-body__text .line:nth-child(5),
.connect__list li:nth-child(5) { animation-delay: 0.9s; }

@media (prefers-reduced-motion: reduce) {
  .about-hero .line,
  .project-body__text .line,
  .connect__list li {
    animation: none;
    opacity: 1;
  }
}






/* ---------- Theme toggle (10×10 icon, 24×24 hit area) ---------- */
.nav__toggle {
  grid-column: -2 / -1;          /* always the last column */
  justify-self: end;
  align-self: center;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end; 
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--color-ink);
}
.nav__toggle:hover { color: var(--color-muted); }
.nav__toggle:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
  border-radius: 50%;
}
/* Both icons are the same simple circle, 10×10.
   currentColor flips between dark and light by theme so the
   shape stays identical and only the fill changes.            */
.nav__toggle__icon--sun  { display: block; width: 10px; height: 10px; }
.nav__toggle__icon--moon { display: none;  width: 10px; height: 10px; }
[data-theme="dark"] .nav__toggle__icon--sun  { display: none;  }
[data-theme="dark"] .nav__toggle__icon--moon { display: block; }

@media (max-width: 1279px) {
  /* Tablet (8 cols) — menu still spans 2 cols starting at 3 */
  .nav__menu { grid-column: 3 / span 2; }
}
@media (max-width: 799px) {
  .nav-row {
    grid-template-columns: auto 1fr auto 2fr auto;
    /* brand | bigger flex space | pills | smaller flex space | toggle */
    column-gap: 0;
    padding-top: 14px;
    padding-bottom: 14px;
  }
  .nav__brand { grid-column: 1; }
  .nav__menu  {
    grid-column: 3;
    display: flex;
    gap: 10px;
  }
  .nav__right { grid-column: 5; }
  .nav__menu > .nav__link { margin-left: 0; }
  .nav__menu__pair { display: contents; }
}

/* ---------- Floating bottom nav --------------------------- */
.nav-floating {
  position: fixed;
  left: 50%;
  bottom: 20px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  background: var(--color-placeholder);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  transform: translate(-50%, calc(100% + 40px));
  opacity: 0;
  pointer-events: none;
  transition:
    transform .45s cubic-bezier(.2, .7, .2, 1),
    opacity .25s ease;
}
.nav-floating--visible {
  transform: translate(-50%, 0);
  opacity: 1;
  pointer-events: auto;
}
.nav-floating__pill {
  display: inline-block;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  color: var(--color-ink);
  font-size: 12px;
  line-height: 1;
  border: 1px solid transparent;
  transition: border-color .15s ease;
}
.nav-floating__pill:hover,
.nav-floating__pill[aria-current="page"] {
  border-color: var(--color-ink);
}
@media (prefers-reduced-motion: reduce) {
  .nav-floating { transition: opacity .2s ease; transform: translate(-50%, 24px); }
  .nav-floating--visible { transform: translate(-50%, 0); }
}
@media (max-width: 799px) {
  .nav-floating {
    gap: 2px;
    padding: 4px 4px 4px 5px;   /* top right bottom left */
    bottom: 14px;
  }
  .nav-floating__pill { padding: 5px 9px; }
}


/* Scroll-to-top button — appears bottom right in sync with the
   floating bar. Clicking smooth-scrolls back to the top.        */
.scroll-top {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 60;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-bg);
  border: none;
  padding: 8px;
  cursor: pointer;
  color: var(--color-ink);

  opacity: 0;
  transform: translateY(40px);
  pointer-events: none;
transition:
  transform .45s cubic-bezier(.2, .7, .2, 1),
  opacity .25s ease,
  background-color .15s ease;
}
.scroll-top--visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.scroll-top:hover,
.scroll-top:focus-visible {
  background: var(--color-muted);
  outline: none;
}

.scroll-top svg {
  width: 100%;
  height: 100%;
  display: block;
}
@media (max-width: 799px) {
  .scroll-top {
    right: 15px;
    bottom: 14px;
    width: 30px;
    height: 30px;
    padding: 4px;
  }
}

/* ---------- Footer ----------
   Pinned to the bottom of the viewport (via main { flex: 1 }
   above). 20px gap between the copyright text and the page
   edge.                                                       */
.footer-row {
  padding-top: 40px;
  padding-bottom: 20px;
}
.footer__copy {
  grid-column: 1 / -1;
  font-size: var(--fs-b2);
  line-height: var(--lh-b2);
}

/* ---------- Read more pill ---------- */
.read-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-b1);
  margin-top: 6px;
}
.read-toggle:hover { text-decoration: underline; }

/* ---------- Image container spec ------------------------
   Two sizes only — "full" and "half" — chosen by breakpoint.
     Desktop  full 16:9    half 1:1     radius 10px
     Tablet   full 16:9    half 1:1     radius  8px
     Mobile   single  290 / 350         radius  6px
   On mobile, two-up rows collapse to a single column and
   every figure adopts the mobile single aspect.
   --------------------------------------------------------- */
:root {
  --media-radius: 10px;
  --media-aspect-full: 16 / 9;
  --media-aspect-half: 1  / 1;
}
@media (max-width: 1279px) {
  :root {
    --media-radius: 8px;
  }
}
@media (max-width: 799px) {
  :root {
    --media-radius: 6px;
    --media-aspect-full: 290 / 350;
    --media-aspect-half: 290 / 350;
  }
}

/* Entrance animation — 5 touching dots fade in one by one, only
   on first visit/reload (same flag as the hero-morph intro). */
.intro-dots {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  width: 100svw;          /* small viewport width — accounts for safe areas */
  height: 100vh;
  height: 100svh;         /* small viewport height — sits inside the visible area */
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  background: var(--color-bg);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
.intro-dots > span {
  width: 18vw;
  height: 18vw;
  border-radius: 50%;
  background: var(--color-ink);
  opacity: 0;
  transform: scale(0.6);
}

body[data-intro] .intro-dots {
  opacity: 1;
  visibility: visible;
  animation: intro-fade-out 0.6s ease 2s forwards;
}
body[data-intro] .intro-dots > span {
  animation: intro-dot-in 0.4s cubic-bezier(.2, .7, .2, 1) forwards;
}
body[data-intro] .intro-dots > span:nth-child(1) { animation-delay: 0.1s; }
body[data-intro] .intro-dots > span:nth-child(2) { animation-delay: 0.3s; }
body[data-intro] .intro-dots > span:nth-child(3) { animation-delay: 0.5s; }
body[data-intro] .intro-dots > span:nth-child(4) { animation-delay: 0.7s; }
body[data-intro] .intro-dots > span:nth-child(5) { animation-delay: 0.9s; }

@keyframes intro-dot-in {
  to { opacity: 1; transform: scale(1); }
}
@keyframes intro-fade-out {
  to { opacity: 0; visibility: hidden; }
}

/* ---------- Page: Home ----------
   A single full-width media container, ready to host a
   <video> showreel.
   The aspect ratio drives shape, but a viewport-aware
   max-height keeps the footer above the fold even on short
   laptop screens — that's the "no scroll on home" rule.
   --chrome accounts for nav (~52) + margin-top (28) + footer
   (~80) + a small safety margin.
*/
.home-hero {
  grid-column: 1 / -1;
  margin-top: 0;            /* 20px gap is provided by nav padding-bottom */
  width: 100%;
  aspect-ratio: var(--media-aspect-full);
  background: var(--color-placeholder);
  overflow: hidden;
  border-radius: var(--media-radius);
}


.home-hero img,
.home-hero video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Home hero wrapped in a link → /work. The link is display:
   contents so it doesn't add its own box; the figure keeps
   its grid placement. Disabled during the intro morph.           */
.home-hero-link {
  display: contents;
  cursor: pointer;
}

/* Home page only — hero stretches to fill main, footer
   sits 20 px below it.                                          */
body[data-page="home"] main {
  grid-template-rows: 1fr;
  align-items: stretch;
}

body[data-page="home"] .footer-row {
  padding-top: 20px;
}

/* Desktop only — every full-width (1-col) image container
   matches the home hero: full grid content width (viewport
   minus the 20px page margins on each side) and viewport
   minus nav (52) and footer (52) for height.                  */
@media (min-width: 1280px) {
  .work-card,
  .project-hero,
  .project-row--single figure,
  .home-hero {
    aspect-ratio: auto;
    width: 100%;
    height: calc(100vh - 104px);
  }
}


/* Tablet — home hero fills the viewport like on desktop */
@media (min-width: 800px) and (max-width: 1279px) {
  .home-hero {
    aspect-ratio: auto;
    width: 100%;
    height: calc(100vh - 104px);
  }
}






/* ---------- Page: Work (work.html) ----------
   Each card spans the full width of the grid, stacked.       */
.work-list { grid-column: 1 / -1; display: flex; flex-direction: column; gap: var(--gutter); margin-top: 0; }
.work-card {
  position: relative;
  display: block;
  background: var(--color-placeholder);
  overflow: hidden;
  aspect-ratio: var(--media-aspect-full);
  border-radius: var(--media-radius);
}
.work-card img,
.work-card video { width: 100%; height: 100%; object-fit: cover; transition: transform .6s ease; }
.work-card:hover img { transform: scale(1.02); }
.work-card--placeholder {
  background:
    linear-gradient(135deg, var(--color-placeholder-2) 25%, transparent 25%) -8px 0,
    linear-gradient(225deg, var(--color-placeholder-2) 25%, transparent 25%) -8px 0,
    linear-gradient(315deg, var(--color-placeholder-2) 25%, transparent 25%),
    linear-gradient(45deg,  var(--color-placeholder-2) 25%, transparent 25%),
    var(--color-placeholder);
  background-size: 16px 16px;
}
/* Project title — styled as a nav-link pill.
   Stroke is transparent until you hover the card.            */
.work-card__caption {
  position: absolute;
  inset: auto auto 12px 10px;
  font-size: 12px;
  line-height: 1;
  color: var(--color-ink);
  background: var(--color-bg);
  border: 1px solid transparent;
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  transition: border-color .15s ease;
}
.work-card__caption:hover,
.work-card:focus-visible .work-card__caption {
  border-color: var(--color-ink);
}



/* ---------- Page: About ----------
   Hero text:    span 10 desktop, 7 tablet, 6 mobile
   Portrait:     Left side (1 to half)
   CV sections:  Right side (half to -1)
*/
.about-hero {
  grid-column: 4 / -1;            /* Remains aligned with project-body */
  margin-top: 0;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: 500;
  letter-spacing: -0.015em;
}

.about-portrait {
  grid-column: 1 / span 2;        /* Desktop: Spans 6 of 12 (exactly half) */
  margin-top: 20px;
  aspect-ratio: 4 / 5;
  background: var(--color-placeholder);
  overflow: hidden;
  border-radius: var(--media-radius);
  position: relative;
  cursor: pointer;
}

.cv-stack {
  grid-column: 1 / 5;
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 0px;
}

.about-portrait canvas {
  display: block;
  border-radius: inherit;
}

.about-portrait img { 
  width: 100%; 
  height: 100%; 
  object-fit: cover; 
}

/* Tablet 800–1279 (8 cols) */
@media (max-width: 1279px) {
  .about-hero { 
    grid-column: 4 / -1; 
  }
  .about-portrait { 
    grid-column: 1 / span 2;      /* Tablet: Spans 4 of 8 (exactly half) */
  }
  .cv-stack { 
    grid-column: 1 / 5;          /* Tablet: Starts at 5, fills remaining 4 cols */
  }
}

/* Mobile 1–799 (6 cols) */
@media (max-width: 799px) {
  .about-hero { 
    grid-column: 1 / -1; 
  }
  .about-portrait { 
    grid-column: 1 / -1;          /* Stacked on mobile */
    margin-top: 20px; 
  }
  .cv-stack { 
    grid-column: 1 / -1;          /* Stacked on mobile */
    margin-top: 20px ;
  }
}

@media (min-width: 1280px) {
  body[data-page="about"] { 
    overflow: auto; 
    height: 100vh; 
  }
}

/* CV — Individual Section Spans */
.cv-section {
  grid-column: 1 / -1;            /* Spans full width of the cv-stack container */
  margin-top: 40px;
}

.cv-section:first-child {
  margin-top: 0;                  /* Remove top margin from first list item */
}

.cv-section__label {
  font-size: var(--fs-b1);        
  line-height: var(--lh-b1);
  font-weight: 500;
  margin-bottom: 20px;
  color: var(--color-ink);
  text-transform: none;
}

.cv-list { 
  display: flex; 
  flex-direction: column; 
  gap: 14px; 
}

.cv-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 20px;
}

.cv-row__title  { font-weight: 500; }
.cv-row__detail { color: var(--color-muted); margin-left: 6px; }
.cv-row__date   { color: var(--color-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cv-row__sub {
  grid-column: 1 / -1;
  color: var(--color-muted);
  font-size: var(--fs-b1);
  line-height: var(--lh-b1);
  margin-top: 2px;
}


/* ---------- Page: Connect ----------
   Links sit in the same column band as the hero text on
   /about and /project (col 4 → end), left-aligned.
   Text is lowercase to match the nav language.
   Sits 0 px below the nav (in addition to the nav's 20 px
   bottom padding).                                           */
.connect {
  grid-column: 1 / -1;
  margin-top: 0px;
}
.connect__list {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: -0.015em;
  padding-left: 0;        /* kill the browser's default ul indent */
  margin: 0;              /* and the default top/bottom margin */
  list-style: none;       /* belt-and-suspenders — kill bullets */
}

.connect__list a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

@media (max-width: 799px) {
  .connect {
    margin-top: 20px;          
  }
}

/* ---------- Project detail page ----------
   Two-column header on desktop & tablet:
     title block (cols 1–3) + body (cols 4–12)                  */
.project-title {
  grid-column: 1 / span 3;
  margin-top: 0;
}
.project-title__name { font-weight: 600; font-size: var(--fs-b1); line-height: var(--lh-b1); }
.project-title__sub  { color: var(--color-muted); margin-top: 2px; font-size: var(--fs-b1); }

.project-body {
  grid-column: 4 / -1;        /* starts at the 4th column */
  margin-top: 0;
}
.project-body__text {
  font-size: var(--fs-h1);    /* 40 / 42 — same as about hero */
  line-height: var(--lh-h1);
  font-weight: 500;
  letter-spacing: -0.015em;
}

@media (max-width: 1279px) {
  .project-title { grid-column: 1 / span 3; }
  .project-body  { grid-column: 4 / -1; }
}
@media (max-width: 799px) {
  .project-title { grid-column: 1 / -1; }
  .project-body  { grid-column: 1 / -1; margin-top: 14px; }
}

/* ---------- Project page media ----------
   Two layouts only:
     .project-row              two half-images side by side
     .project-row--single      one full-width image
   Both honor the breakpoint-driven aspect ratios + radius.    */
.project-hero {
  grid-column: 1 / -1;
  margin-top: 28px;
  width: 100%;
  aspect-ratio: var(--media-aspect-full);
  background: var(--color-placeholder);
  overflow: hidden;
  border-radius: var(--media-radius);
}
.project-hero img,
.project-hero video { width: 100%; height: 100%; object-fit: cover; }

.project-row {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;        /* exactly two boxes */
  column-gap: var(--gutter);             /* 20 / 20 / 15 */
  row-gap: var(--gutter);
  margin-top: var(--gutter);
}
.project-row--single {
  grid-template-columns: 1fr;            /* one box only */
}
.project-row figure {
  background: var(--color-placeholder);
  overflow: hidden;
  aspect-ratio: var(--media-aspect-half);
  border-radius: var(--media-radius);
}
.project-row--single figure {
  aspect-ratio: var(--media-aspect-full);
}
.project-row img,
.project-row video { width: 100%; height: 100%; object-fit: cover; }

/* Mobile: two-up row collapses to single column,
   each figure adopts the mobile single aspect (290/350). */
@media (max-width: 799px) {
  .project-row { grid-template-columns: 1fr; }
}



.work-view-icon { display: none; }

@media (min-width: 1280px) {
  body[data-page="work"] .nav__link--work {
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }
  body[data-page="work"] .nav__work-text {
    color: inherit;
    text-decoration: none;
  }
  body[data-page="work"] .work-view-icon {
    display: inline-flex;
    align-items: center;
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    cursor: pointer;
    color: currentColor;
    line-height: 0;
  }
body[data-page="work"] .work-view-icon.is-active {
    color: var(--color-muted);
  }
  body[data-page="work"] .work-view-icon:hover {
    color: var(--color-muted);
  }
}


@keyframes work-icons-in {
  from { max-width: 0;    margin-left: -6px; opacity: 0; }
  to   { max-width: 16px; margin-left: 0;    opacity: 1; }
}

body[data-page="work"]:not([data-icons-ready]) .work-view-icon {
  overflow: hidden;
  animation: work-icons-in 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
body[data-page="work"]:not([data-icons-ready]) .work-view-icon--stacked { animation-delay: 0.5s; }
body[data-page="work"]:not([data-icons-ready]) .work-view-icon--index   { animation-delay: 0.4s; }



/* ---------- Work — index view ---------- */
.work-index { grid-column: 1 / -1; }

.work-index__label {
  font-size: var(--fs-b1);
  line-height: var(--lh-b1);
  color: var(--color-muted);
  margin: 0 0 calc(var(--gutter) * 2);
}

.work-index__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.work-index__item {
  border-bottom: 1px solid var(--color-ink);
}

.work-index__link {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: baseline;
  gap: var(--gutter);
  padding: 8px 0 0px ; 
  color: var(--color-ink);
  text-decoration: none;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.work-index__link:hover { color: var(--color-muted); }
.work-list[hidden],
.work-index[hidden] { display: none !important; }




/* Mobile: scroll-top sits inside the floating bar.
   Only override what's needed to detach it from the fixed
   bottom-right corner; keep the round dot background, size,
   padding, and SVG sizing from the base .scroll-top rules. */
@media (max-width: 799px) {
  .scroll-top.scroll-top--in-bar {
    position: static;
    transform: none;
    opacity: 1;
    pointer-events: auto;
    width: 27px;
    height: 27px;
    padding: 7px;
  }
}


/* Hide the scroll-top button on /about and /connect, desktop only.
   Tablet and mobile still show it (mobile integrates it into the
   floating bar as before). */
@media (min-width: 1280px) {
  body[data-page="about"] .scroll-top,
  body[data-page="connect"] .scroll-top {
    display: none;
  }
}


/* Mobile home page — fit-to-viewport, no scroll.
   Body fills the small viewport height (100svh handles mobile
   browser chrome correctly). Nav and footer keep their natural
   height; main flexes to fill the rest; hero fills main. */
@media (max-width: 799px) {
  body[data-page="home"] {
    height: 100vh;          /* fallback */
    height: 100svh;         /* "small viewport" — accounts for safari/chrome address bars */
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
  body[data-page="home"] main {
    flex: 1;
    min-height: 0;          /* let main shrink instead of overflowing */
  }
  body[data-page="home"] .home-hero {
    aspect-ratio: auto;
    max-height: none;
    height: 100%;
    min-height: 0;
  }
}

/* Sub-330px phones — tighten the gap between work/about/connect
   without shrinking the pill stroke itself. */
@media (max-width: 330px) {
  .nav__menu .nav__link:not(:first-child) { margin-left: -8px; }
}


/* Wrapper around hero + thumb strip — gives thumbs a positioning context */
.home-hero-stack {
  grid-column: 1 / -1;
  position: relative;
  width: 100%;
}

/* Home page image selector — mirrors the floating bar
   navigation: pill-shaped gray container, white circular
   buttons inside, same dimensions as scroll-top. */
.home-thumbs {
  position: absolute;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  background: var(--color-placeholder);
  border-radius: var(--radius-pill);
  z-index: 5;
}

.home-thumbs__item {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  overflow: hidden;
  display: block;
  transition: box-shadow .15s ease;
}

.home-thumbs__item:hover,
.home-thumbs__item.is-active {
  box-shadow: 0 0 0 1px var(--color-ink);
}


.home-thumbs__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Hide on mobile and tablet — desktop only feature */
@media (max-width: 1279px) {
  .home-thumbs { display: none; }
}

/* Home hero — stacked images, only one visible at a time.
   The visible one is decided by the JS scrubber/autoplay. */
.home-hero { position: relative; }

.home-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}
.home-hero__img.is-visible {
  opacity: 1;
}


/* Project hero with a video — let the video's natural aspect ratio
   define the container shape; video fills 100% of the width. */
.project-hero.figure--video {
  aspect-ratio: auto;
  height: auto;
}
.project-hero.figure--video video {
  width: 100%;
  height: auto;
  display: block;
}

/* Override the desktop "fill viewport height" rule for video heroes */
@media (min-width: 1280px) {
  .project-hero.figure--video {
    height: auto;
  }
}


/* Project video — custom play/pause overlay.
   The button mirrors the scroll-top dot pattern, sized 28×28,
   centered on the video, rotated 90° clockwise to read as "play". */
.video-wrap {
  position: relative;
}

.video-play-toggle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(90deg);
  z-index: 10;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 0;
  padding: 8px;
  cursor: pointer;
  color: var(--color-ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.video-wrap.is-paused .video-play-toggle {
  opacity: 1;
  pointer-events: auto;
}
.video-play-toggle svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Hide browser-default video UI (the "tap to play" overlay that
   appears when autoplay is blocked, etc.). The script still handles
   click-to-toggle, so users on autoplay-blocking browsers can still
   start the video by tapping it. */
.project-hero video::-webkit-media-controls,
.project-row video::-webkit-media-controls,
.project-hero video::-webkit-media-controls-start-playback-button,
.project-row video::-webkit-media-controls-start-playback-button,
.project-hero video::-webkit-media-controls-overlay-play-button,
.project-row video::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
}


/* Override aspect-ratio / fixed-height for figures that should be
   100vh tall instead. Use with: <figure class="figure--tall"> */
.project-row--single .figure--tall {
  aspect-ratio: auto;
  height: 100vh;
}

@media (min-width: 1280px) {
  .project-row--single .figure--tall {
    height: 100vh;
  }
}

/* Videos in single-column rows: let the video's natural ratio
   define the container shape, so it fills 100% width with no crop. */
.project-row--single .figure--video {
  aspect-ratio: auto;
  height: auto;
}
.project-row--single .figure--video video {
  width: 100%;
  height: auto;
}

@media (min-width: 1280px) {
  .project-row--single .figure--video {
    height: auto;
  }
}



/* Project hero with natural aspect — let the image's true
   proportions define the container; image fills 100% width. */
.project-hero.figure--natural,
.project-row--single .figure--natural {
  aspect-ratio: auto;
  height: auto;
}
.project-hero.figure--natural img,
.project-hero.figure--natural video,
.project-row--single .figure--natural img,
.project-row--single .figure--natural video {
  width: 100%;
  height: auto;
}

@media (min-width: 1280px) {
  .project-hero.figure--natural,
  .project-row--single .figure--natural {
    height: auto;
  }
}