/* =====================================================================
   Home page v2 — sticky sidebar + content grid
   Scoped to body.home-v2 so the shared styles.css (case studies,
   experience, gallery) stays untouched.
   ===================================================================== */

.home-v2 {
  --aside-w: 360px;
  --gutter: 24px;       /* outer page edge — the same on the left (sidebar) and right (content) */
  --gap: 16px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.25, 0.64, 1);
}

/* ===== Colour tokens =====
   One neutral palette for the whole shell. Overrides the base values from
   styles.css (this file loads after it), so case content picks it up too.
   Surfaces follow a 3-step scale: page → card → hover. */
:root {
  --bg-0: #0E0E0F;                         /* page — deep, strictly neutral */
  --bg-1: #1C1C1E;                         /* cards, tiles, image mats */
  --surface-hover: #242426;                /* hover on cards / tiles */

  --text-primary: rgba(255, 255, 255, 0.92);    /* 16.3:1 */
  --text-secondary: rgba(255, 255, 255, 0.68);  /*  9.1:1 */
  --text-tertiary: rgba(255, 255, 255, 0.52);   /*  5.7:1 */
  --text-quaternary: rgba(255, 255, 255, 0.46); /*  4.7:1 — passes WCAG AA */

  --hairline: rgba(255, 255, 255, 0.07);   /* dividers */
  --border-subtle: rgba(255, 255, 255, 0.04);
  --header-bg: rgba(14, 14, 15, 0.85);

  --glass: rgba(28, 28, 30, 0.6);          /* nav capsule at rest */
  --glass-stuck: rgba(28, 28, 30, 0.86);   /* nav capsule floating over content */
  --glass-solid: #1C1C1E;                  /* nav capsule during page transitions */
  --chip-glass: rgba(14, 14, 15, 0.72);    /* zoom hint on screenshots */
  --overlay: rgba(6, 6, 7, 0.92);          /* lightbox backdrop */

  /* Inline links = the one accent; lighter on hover */
  --link: var(--green);
  --link-hover: #FFB66A;

  /* Media frames ("passe-partout" around every screenshot / video) */
  --frame-bg: #18181A;                     /* 1.09:1 to the page — present, but quiet */
  --frame-bg-hover: #1E1E20;
  --frame-radius: 16px;                    /* one radius for every frame and card */
  --radius-card: 16px;
  --radius-img: 8px;                       /* media inside a frame */

  /* accent-tinted result cards: same recipe, on the shared card surface */
  --creator-card-bg: linear-gradient(90deg, rgba(255, 160, 60, 0.07), rgba(255, 160, 60, 0.07)),
                     linear-gradient(90deg, #1C1C1E, #1C1C1E);
  --creator-card-border: rgba(255, 160, 60, 0.08);
}

/* Link rule.
   · Actions (.hl-ext--action: View live, case study…) carry the site's one accent —
     they're what the reader should click.
   · Inline links (in text or a heading: company names, URLs) stay quiet grey with a ↗;
     no underline at rest — it grows in on hover and stops short of the arrow.
   · Contacts (email, LinkedIn, X) stay neutral utility links. */
.link-external {
  --arrow-space: 0px;
  display: inline;
  align-self: flex-start; /* hug the text when it sits in a flex column */
  color: var(--text-tertiary);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: color 0.25s ease, background-size 0.4s var(--ease-out);
}

.link-external[target="_blank"] {
  --arrow-space: 0.8em;
}

/* Inside a heading or a line of text the link takes that text's type, not its own */
:is(h1, h2, h3, h4, p, li) .link-external {
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}

.link-external[target="_blank"]::after {
  content: "";
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  margin-left: 0.2em;
  vertical-align: 0.05em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 9L9 3M9 3H4M9 3V8' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 9L9 3M9 3H4M9 3V8' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.7;
  transition: transform 0.35s var(--ease-out), opacity 0.25s ease;
}

.link-external:hover {
  color: var(--text-primary);
  background-size: calc(100% - var(--arrow-space)) 1px;
}

.link-external:hover::after {
  opacity: 1;
  transform: translate(2px, -2px);
}


.home-v2 ::selection {
  background: rgba(255, 160, 60, 0.3);
  color: #fff;
}

/* Keyboard focus — one consistent ring everywhere on the page */
.home-v2 :focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: 8px;
}

/* ===== Layout ===== */
.hl {
  display: grid;
  grid-template-columns: var(--aside-w) minmax(0, 1fr);
  max-width: 1680px;
  margin: 0 auto;
}

/* ===== Sidebar ===== */
.hl-aside {
  align-self: start;
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: var(--gutter) 40px 32px var(--gutter); /* top = side edge */
  overflow-y: auto;
  scrollbar-width: none;
}

.hl-aside::-webkit-scrollbar { display: none; }

.hl-avatar {
  display: block;
  width: 56px;
  height: 56px;
  margin-bottom: 20px;
  border-radius: 50%;
  background: var(--bg-1);
  -webkit-tap-highlight-color: transparent;
}

.hl-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  transition: scale 0.3s var(--ease-out);
}

.hl-avatar:active img {
  scale: 0.94;
  transition-duration: 0.12s;
}

.hl-name {
  font-size: 17px;
  font-weight: 600;
  line-height: 25px;
  letter-spacing: -0.085px;
  color: var(--white-90);
}

/* Type rule: text is Body S Regular (15/23); anything you can click — nav tabs,
   links, actions, contacts — is Body S Semibold, so weight alone signals "clickable".
   The name is the one larger accent (17 / semibold / white).
   Colours: meta (role, place, status) 52% · bio 68% · email white · social links 52%. */
.hl-role {
  margin-top: 2px;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

.hl-status {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 20px; /* its own block under the bio — same gap as above the bio */
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

.hl-bio {
  margin-top: 20px;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-70);
  max-width: 280px;
}

/* ----- Contacts ----- */
.hl-contact {
  margin-top: auto;
  padding-top: 40px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.hl-copy {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-90);
}

/* Default / done labels share one grid cell and slide past each other */
.hl-copy-text {
  display: inline-grid;
  overflow: hidden;
  text-align: left;
}

.hl-copy-default,
.hl-copy-done {
  grid-area: 1 / 1;
  transition: transform 0.45s var(--ease-out), opacity 0.3s ease, filter 0.3s ease;
}

.hl-copy-done {
  transform: translateY(100%);
  opacity: 0;
  filter: blur(4px);
  color: var(--green);
}

.hl-copy.is-copied .hl-copy-default {
  transform: translateY(-100%);
  opacity: 0;
  filter: blur(4px);
}

.hl-copy.is-copied .hl-copy-done {
  transform: none;
  opacity: 1;
  filter: none;
}

.hl-copy-icon {
  position: relative;
  width: 16px;
  height: 16px;
  color: var(--white-40);
  transition: color 0.25s ease;
}

.hl-copy-icon svg {
  position: absolute;
  inset: 0;
  transition: transform 0.35s var(--ease-spring), opacity 0.2s ease;
}

.hl-copy:hover .hl-copy-icon { color: var(--white-90); }

.hl-copy .i-check {
  opacity: 0;
  transform: scale(0.6);
  color: var(--green);
}

.hl-copy .i-check path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 0.35s var(--ease-out) 0.08s;
}

.hl-copy.is-copied .i-copy {
  opacity: 0;
  transform: scale(0.6);
}

.hl-copy.is-copied .i-check {
  opacity: 1;
  transform: none;
}

.hl-copy.is-copied .i-check path {
  stroke-dashoffset: 0;
}

.hl-copy:active .hl-copy-icon {
  transform: scale(0.85);
}

.hl-socials {
  display: flex;
  gap: 20px;
}

.hl-ext {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 15px;
  font-weight: 600;
  line-height: 19px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

.hl-ext svg {
  color: var(--white-40);
  transition: transform 0.35s var(--ease-out), color 0.25s ease;
}

.hl-ext:hover { color: var(--white-90); }

.hl-ext:hover svg {
  color: var(--white-90);
  transform: translate(2px, -2px);
}

.hl-ext--action,
.hl-ext--action svg {
  color: var(--link);
}

.hl-ext--action:hover,
.hl-ext--action:hover svg {
  color: var(--link-hover);
}

/* ----- Sidebar intro (first load only) ----- */
.home-v2.is-intro [data-intro] {
  opacity: 0;
  transform: translateY(8px);
  filter: blur(6px);
}

.home-v2 [data-intro] {
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out), filter 0.9s var(--ease-out);
}

.home-v2 .hl-navbar[data-intro] { transition-delay: 0.08s; }
.home-v2 .hl-contact[data-intro] { transition-delay: 0.16s; }

/* ===== Main column ===== */
.hl-main {
  min-width: 0;
  /* top = side edge (--gutter): capsule and avatar share one top line */
  /* the page ends on the last Playground tile — one section gap of air below it */
  padding: var(--gutter) var(--gutter) 96px 48px;
}

.hl-section + .hl-section {
  margin-top: 96px;
}

.hl-section {
  /* land sections just below the floating capsule */
  scroll-margin-top: calc(var(--nav-top) + var(--nav-h) + var(--nav-gap));
}

.hl-section-head {
  padding: 0 4px;
  margin-bottom: 24px;
}

.hl-section-title {
  font-size: 21px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: -0.21px;
  color: var(--white-90);
}

.hl-section-sub {
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

/* ===== Floating section switcher ===== */
.home-v2 {
  --nav-h: 44px;        /* capsule height: 4px inset + 36px links + 4px inset */
  --nav-top: 24px;      /* = --gutter: sticks exactly where it first appears — one position */
  --nav-gap: 24px;      /* space between capsule and content below */
}

.hl-navbar {
  position: sticky;
  top: var(--nav-top);
  z-index: 40;
  display: flex;
  justify-content: center;
  margin-bottom: var(--nav-gap);
  pointer-events: none; /* only the capsule itself is interactive */
}

.hl-nav {
  position: relative;
  display: flex;
  align-items: center;
  padding: 4px;
  border-radius: 999px;
  background: var(--glass);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06),
              0 0 0 0 rgba(0, 0, 0, 0);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  pointer-events: auto;
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}

/* Once it floats over content it gets denser and lifts off the page */
.hl-navbar.is-stuck .hl-nav {
  background: var(--glass-stuck);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08),
              0 12px 32px -12px rgba(0, 0, 0, 0.7);
}

.hl-nav-pill {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  opacity: 0;
  pointer-events: none;
  will-change: transform, width;
  /* position/size are driven by a JS spring (home.js); only the fade is CSS */
  transition: opacity 0.25s ease;
}

.hl-nav.is-ready:not(.no-pill) .hl-nav-pill { opacity: 1; }

.hl-nav-link {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  line-height: 19px;
  letter-spacing: -0.03px;
  color: var(--white-50);
  white-space: nowrap;
  transition: color 0.25s ease;
  -webkit-tap-highlight-color: transparent;
}

.hl-nav-link:hover,
.hl-nav-link.is-active {
  color: var(--white-90);
}

.hl-nav-link:focus-visible {
  border-radius: 999px;
  outline-offset: 0;
}

.hl-nav-count {
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0;
  color: var(--white-40);
  font-variant-numeric: tabular-nums;
  transition: color 0.25s ease;
}

.hl-nav-link.is-active .hl-nav-count { color: var(--white-50); }

.hl-nav-sep {
  flex: none;
  width: 1px;
  height: 16px;
  margin: 0 4px;
  background: rgba(255, 255, 255, 0.1);
}

.hl-nav-link--page { padding-right: 10px; gap: 2px; }

.hl-nav-icon {
  color: var(--white-40);
  transition: transform 0.35s var(--ease-out), color 0.25s ease;
}

.hl-nav-link:hover .hl-nav-icon {
  transform: translateX(2px);
  color: var(--white-90);
}

/* ===== Works ===== */
.works-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap);
}

.work-card {
  --mx: 50%;
  --my: 0%;
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  padding: 28px;
  border-radius: var(--frame-radius);
  background: var(--bg-1);
  overflow: hidden;
  color: inherit;
  transition: transform 0.5s var(--ease-out), background-color 0.4s ease;
  -webkit-tap-highlight-color: transparent;
}

.work-card:hover { color: inherit; }

/* Tactile press */
.work-card:active {
  transform: scale(0.985);
  transition-duration: 0.15s;
}

/* Cursor-following spotlight tinted with the project's brand colour */
.work-spot {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(420px circle at var(--mx) var(--my),
              color-mix(in srgb, var(--accent) 16%, transparent),
              transparent 70%);
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* Resting state: faint static brand tint so cards differ at a glance */
.work-card::before {
  content: "";
  position: absolute;
  z-index: -2;
  left: 50%;
  top: 0;
  width: 80%;
  height: 45%;
  transform: translate(-50%, -30%);
  background: radial-gradient(ellipse at center, var(--accent), transparent 70%);
  opacity: 0.1;
  filter: blur(50px);
  pointer-events: none;
  transition: opacity 0.5s ease;
}

@media (hover: hover) and (pointer: fine) {
  .work-card:hover .work-spot { opacity: 1; }
  .work-card:hover::before { opacity: 0.04; }
}

.work-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.work-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 21px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: -0.21px;
  color: var(--white-90);
}

.work-desc {
  margin-top: 4px;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

/* Arrow chip: on hover the arrow flies out and a copy flies back in */
.work-arrow {
  position: relative;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--white-50);
  overflow: hidden;
  transition: background-color 0.3s ease, color 0.3s ease;
}

.work-arrow svg {
  position: absolute;
  top: 8px;
  left: 8px;
  transition: transform 0.45s var(--ease-out);
}

.work-arrow svg + svg { transform: translateX(-24px); }

.work-arrow--ext svg + svg { transform: translate(-24px, 24px); }

.work-card:hover .work-arrow {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--white-90);
}

.work-card:hover .work-arrow svg:first-child { transform: translateX(24px); }
.work-card:hover .work-arrow svg + svg { transform: none; }
.work-card:hover .work-arrow--ext svg:first-child { transform: translate(24px, -24px); }

.work-head {
  margin-bottom: 24px;
}

/* Pinned to the bottom so previews line up across a row even when descriptions wrap */
.work-media {
  margin-top: auto;
  border-radius: 10px;
  overflow: hidden;
  transform-origin: 50% 100%;
  transition: transform 0.7s var(--ease-out);
}

.work-media img,
.work-media video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1440 / 836; /* matches the Vocabulary video; screenshots crop a sliver at the bottom */
  object-fit: cover;
  object-position: top;
}

.work-card:hover .work-media {
  transform: translateY(-4px) scale(1.012);
}

/* Craftify: phones stand on the card's bottom edge, full-bleed */
.work-card--flush {
  padding-bottom: 0;
}

.work-card--flush .work-media {
  margin: auto -28px 0;
  border-radius: 0;
}

.work-card--flush .work-media img {
  object-fit: contain;
  object-position: bottom;
}

/* ===== Playground ===== */
.pg-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* caption sits 12px under its tile; the next tile is 40px away (all widths) */
  gap: 40px var(--gap);
}

.pg-item {
  margin: 0;
  min-width: 0;
  /* the frame's padding is measured against this box (cqi) */
  container-type: inline-size;
  display: flex;
  flex-direction: column;
}

.pg-item--wide {
  grid-column: 1 / -1;
}

/* Frame rule: padding = 5% of the frame width (16–40px), media keeps its own
   proportions and is never cropped. Frames in one row share a height (the grid
   stretches them); a shorter piece of media is centred in its frame. */
.pg-tile {
  --frame-pad: clamp(16px, 5cqi, 40px);
  --card-padding: var(--frame-pad); /* consumed by the shared slideshow styles */
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: var(--frame-pad);
  border: 0;
  border-radius: var(--frame-radius);
  background: var(--frame-bg);
  cursor: zoom-in;
  overflow: hidden;
  transition: background-color 0.4s ease, transform 0.5s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

.pg-tile > img,
.pg-tile > video {
  display: block;
  width: 100%;
  height: auto;       /* proportions come from the width/height attributes */
  border-radius: var(--radius-img);
  transition: transform 0.7s var(--ease-out), opacity 0.4s ease;
}

/* Portrait screens (phones): fixed height, natural width, centred */
.pg-tile--portrait > img,
.pg-tile--portrait > video {
  width: auto;
  height: min(520px, 110cqi);
}

.pg-tile > img:not(.slideshow-img) {
  opacity: 0;
}

.pg-tile > img.is-loaded {
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  .pg-tile:hover {
    background: var(--frame-bg-hover);
  }
  .pg-tile:hover > img,
  .pg-tile:hover > video {
    transform: scale(1.02);
  }
}

.pg-tile:active {
  transform: scale(0.99);
  transition-duration: 0.15s;
}

/* Hint icon in the corner — tells you the tile opens bigger */
.pg-tile::after,
.zoom-card::after {
  content: "";
  position: absolute;
  top: 12px;
  right: 12px;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: var(--chip-glass) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M8.5 2.5H11.5V5.5M5.5 11.5H2.5V8.5M11.5 2.5L8 6M2.5 11.5L6 8' stroke='white' stroke-opacity='0.9' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 14px no-repeat;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.25s ease, transform 0.35s var(--ease-spring);
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .pg-tile:hover::after,
  .zoom-card:hover::after {
    opacity: 1;
    transform: none;
  }
}

.pg-item figcaption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
  padding: 0 4px;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
  transition: color 0.3s ease;
}

.pg-item:hover figcaption {
  color: var(--white-70);
}

.pg-item figcaption .hl-ext {
  flex-shrink: 0;
}

/* ===== Back to top (contact row on reading pages) ===== */
.hl-top {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--white-50);
  cursor: pointer;
  transition: color 0.25s ease;
}

.hl-top svg {
  transition: transform 0.4s var(--ease-out);
}

.hl-top:hover { color: var(--white-90); }
.hl-top:hover svg { transform: translateY(-3px); }

/* ===== Scroll reveal (staggered per row) ===== */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
  transition-delay: var(--d, 0s);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* Once revealed, drop the delay so hover transforms feel instant */
.reveal.is-settled {
  transition-delay: 0s;
}

/* Work cards set their own transform transition — keep the reveal on top of it */
.work-card.reveal {
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out), background-color 0.4s ease;
  transition-delay: var(--d, 0s);
}

.work-card.reveal.is-settled {
  transition: transform 0.5s var(--ease-out), background-color 0.4s ease;
}

/* The older scroll-reveal used by case-study content (styles.css runs it at 1.6s):
   same 1s and same easing as the home reveal, so the whole site moves as one */
.home-v2 .animate-on-scroll {
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
}

.work-card.reveal.is-settled:active {
  transition-duration: 0.15s;
}

/* ===== Lightbox ===== */
.lb {
  position: fixed;
  inset: 0;
  z-index: 1000;
}

.lb[hidden] { display: none; }

.lb-backdrop {
  position: absolute;
  inset: 0;
  background: var(--overlay);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity 0.4s ease;
  cursor: zoom-out;
}

.lb.is-open .lb-backdrop { opacity: 1; }

.lb-stage {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.lb-media {
  position: absolute;
  border-radius: var(--radius-img);
  object-fit: contain;
  pointer-events: auto;
  transform-origin: 0 0;
  will-change: transform;
  user-select: none;
  -webkit-user-drag: none;
}

.lb-media.is-animating {
  transition: transform 0.5s var(--ease-out), opacity 0.3s ease;
}

.lb-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 20px 24px 24px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s ease, transform 0.4s var(--ease-out);
}

.lb.is-open .lb-bar {
  opacity: 1;
  transform: none;
  transition-delay: 0.1s;
}

.lb-caption {
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-70);
  min-width: 0;
}

.lb-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.lb-count {
  margin-right: 8px;
  font-size: 13px;
  line-height: 18px;
  letter-spacing: 0;
  color: var(--white-40);
  font-variant-numeric: tabular-nums;
}

.lb-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--white-70);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s var(--ease-out);
}

.lb-btn:hover {
  background: rgba(255, 255, 255, 0.14);
  color: var(--white-90);
}

.lb-btn:active { transform: scale(0.92); }

.lb-btn:disabled {
  opacity: 0.3;
  pointer-events: none;
}

/* ===== Responsive ===== */
@media (max-width: 1200px) {
  .home-v2 { --aside-w: 300px; }
  .hl-aside { padding: var(--gutter) 32px 28px var(--gutter); }
  .hl-main { padding-left: 32px; }
  .work-card { padding: 24px; }
  .work-card--flush { padding-bottom: 0; }
  .work-card--flush .work-media { margin: auto -24px 0; }
}

@media (max-width: 1024px) {
  .works-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Mobile / small tablet: sidebar unfolds into the page flow.
   The aside becomes display:contents so the nav can stick across the whole page. */
@media (max-width: 900px) {
  .home-v2 { --gutter: 16px; }

  .hl {
    display: flex;
    flex-direction: column;
  }

  .hl-aside { display: contents; }

  .hl-intro {
    order: 1;
    padding: 40px var(--gutter) 24px;
  }

  .hl-bio { max-width: 520px; }

  .home-v2 { --nav-top: 12px; --nav-gap: 16px; }

  .hl-nav-link { padding: 0 12px; }
  .hl-nav-link--page { padding-right: 8px; }

  .hl-main {
    order: 3;
    padding: 0 var(--gutter);
  }

  .hl-section-head { padding: 0; }

  .hl-contact {
    order: 4;
    padding: 0 var(--gutter) 40px;
    margin-top: 0;
  }

  .hl-main { padding-bottom: 64px; }

  .hl-section + .hl-section { margin-top: 72px; }

  .pg-grid { column-gap: 12px; }
}

@media (max-width: 600px) {
  .pg-grid { grid-template-columns: minmax(0, 1fr); }
  .work-card { padding: 20px; }
  .work-card--flush { padding-bottom: 0; }
  .work-card--flush .work-media { margin: auto -20px 0; }
  .work-head { margin-bottom: 20px; }
  .lb-bar { flex-direction: column; align-items: stretch; gap: 12px; padding: 16px; }
  /* Thumb-friendly: counter left, prev/next centred, close far right —
     next and close are no longer neighbours, so no accidental closes */
  .lb-controls {
    display: grid;
    grid-template-columns: 1fr auto auto 1fr;
    gap: 8px;
  }
  .lb-count { justify-self: start; margin-right: 0; }
  .lb-controls [data-lb-close] { justify-self: end; }
}

@media (prefers-reduced-motion: reduce) {
  .home-v2 *,
  .home-v2 *::before,
  .home-v2 *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
  .reveal { opacity: 1; transform: none; }
  .home-v2.is-intro [data-intro] { opacity: 1; transform: none; filter: none; }
}

/* =====================================================================
   Experience page — same shell, CV-style list
   ===================================================================== */
.exp-list {
  list-style: none;
  max-width: 920px;
}

.exp-item {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 24px;
  padding: 32px 4px;
  border-top: 1px solid var(--hairline);
}

.exp-item:first-child {
  border-top: 0;
  padding-top: 8px;
}

.exp-date {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 8px;
  align-self: start;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-50);
  font-variant-numeric: tabular-nums;
  /* optically align with the 28px title line */
  padding-top: 2px;
}

.exp-date-sub {
  flex-basis: 100%;
  color: var(--white-40);
}

/* "Present" marker: a quiet pulse says this is ongoing */
.exp-now {
  position: relative;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green);
}

.exp-now::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--green);
  animation: expPulse 2.4s var(--ease-out) infinite;
}

@keyframes expPulse {
  0%   { transform: scale(1); opacity: 0.6; }
  70%, 100% { transform: scale(3); opacity: 0; }
}

.exp-title {
  font-size: 21px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: -0.21px;
  color: var(--white-90);
}

.exp-points {
  list-style: none;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.exp-points li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  letter-spacing: -0.03px;
  color: var(--white-70);
}

.exp-points li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 9px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--white-40);
}

.exp-links {
  display: flex;
  gap: 20px;
  margin-top: 16px;
}

/* Internal link: arrow nudges right instead of diagonally */
.hl-ext--in:hover svg {
  transform: translateX(3px);
}

@media (max-width: 1024px) {
  .exp-item {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
  .exp-date { padding-top: 0; }
}

@media (max-width: 900px) {
  .exp-item { padding: 24px 0; }
  .exp-item:first-child { padding-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .exp-now::after { animation: none; }
}

/* =====================================================================
   Reading page (Experience): no sidebar, centred column + back button
   ===================================================================== */
.read {
  max-width: calc(var(--text-max) + 32px);
  margin: 0 auto;
  /* capsule sits at the same height as on the home page */
  padding: var(--gutter) 16px 0;
}

.read-page .hl-navbar {
  margin-bottom: 64px;
}

.read-back {
  position: fixed;
  z-index: 50;
  top: 24px;
  left: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--white-70);
  transition: background-color 0.25s ease, color 0.25s ease, transform 0.3s var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
}

.read-back svg {
  transition: transform 0.35s var(--ease-out);
}

.read-back:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--white-90);
}

.read-back:hover svg { transform: translateX(-3px); }

.read-back:active {
  transform: scale(0.92);
  transition-duration: 0.12s;
}

.read-back:focus-visible { border-radius: 50%; }

.read-head {
  margin-bottom: 40px;
}

.read-title {
  font-size: 31px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.465px;
  color: var(--white-90);
  margin-bottom: 12px;
}

/* In the narrow column the date sits above the role */
.read .exp-list { max-width: none; }

.read .exp-item {
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  padding: 32px 0;
}

.read .exp-item:first-child { padding-top: 0; }

.read .exp-date { padding-top: 0; }

.read-contact {
  margin-top: 64px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
}

@media (max-width: 900px) {
  .read { padding-top: 16px; }
  .read-page .hl-navbar { margin-bottom: 40px; }
  .read-back { top: 16px; left: 16px; width: 44px; height: 44px; }
  .read-title { font-size: 24px; }
  .read .exp-item { padding: 24px 0; }
  .read-contact { padding-left: 0; padding-right: 0; padding-bottom: 0; }
}

/* Reading page: socials left, back-to-top right on the same line */
.read-contact {
  padding-bottom: 48px;
}

.read-contact-row {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.read-contact-row .hl-top {
  font-size: 15px;
  font-weight: 600;
  line-height: 23px;
  letter-spacing: -0.03px;
}

/* =====================================================================
   Page transitions (View Transitions API, cross-document)
   The capsule is the same element on every page, so it morphs in place
   while the page content dissolves underneath it.
   Unsupported browsers simply navigate normally.
   ===================================================================== */
@view-transition {
  navigation: auto;
}

/* The canvas behind the transition must be the page colour — otherwise the moment
   where the old page has faded and the new one hasn't yet shows a white flash
   (very visible in mobile Safari) */
:root {
  color-scheme: dark;
  background-color: var(--bg-0);
}

::view-transition {
  background-color: var(--bg-0);
}

.hl-nav {
  view-transition-name: site-nav;
}

::view-transition-group(*) {
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Show only the live new capsule while it morphs — no cross-fade, so the pill never
   doubles up and the text never ghosts. The pill slides inside it in real time. */
::view-transition-old(site-nav) {
  display: none;
}

::view-transition-new(site-nav) {
  animation: none;
}

/* Snapshots can't sample the backdrop, so the glass would look see-through while it
   moves. Make it solid for the duration; it eases back to glass afterwards. */
:root:active-view-transition .hl-nav {
  background: var(--glass-solid);
}

/* Page content: "fade through" — the old page leaves first, then the new one arrives,
   so the two pages' text never overlaps. Opacity + transform only (GPU-cheap).
   The capsule keeps morphing across the whole 0.5s on top of this. */
::view-transition-old(root) {
  animation: vt-out 0.16s cubic-bezier(0.4, 0, 1, 1) both;
}

::view-transition-new(root) {
  animation: vt-in 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.14s both;
}

@keyframes vt-out {
  to { opacity: 0; }
}

@keyframes vt-in {
  from { opacity: 0; transform: translateY(10px); }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* =====================================================================
   Case studies — same shell as Experience: shared capsule, centred
   column, "Next case" + contacts at the end. Scoped to .case-v2 so the
   case content styles in styles.css stay the single source of truth.
   ===================================================================== */
.case-v2 .case-study {
  /* capsule sits at the same height as on every other page */
  padding-top: var(--gutter);
}

.case-v2 .case-study > .hl-navbar {
  margin-bottom: 64px;
}

/* Zoomable screenshots */
.case-v2 .zoom-card {
  position: relative;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}

.case-v2 .slider-card.zoom-card {
  cursor: inherit; /* the slider keeps its grab cursor — a click without a drag still opens */
}

.case-v2 .zoom-card img,
.case-v2 .zoom-card video {
  transition: transform 0.7s var(--ease-out), opacity 0.4s ease;
}

@media (hover: hover) and (pointer: fine) {
  .case-v2 .zoom-card:hover img,
  .case-v2 .zoom-card:hover video {
    transform: scale(1.01);
  }
}

.case-v2 .zoom-card:focus-visible {
  outline-offset: 4px;
  border-radius: var(--radius-card);
}

/* Paragraph rhythm: section titles get air above when they follow text */
.case-v2 .text-block > .body-text + .subsection-title,
.case-v2 .text-block > .bullet-list + .subsection-title {
  margin-top: 40px;
}

/* ----- End of case ----- */
.case-next {
  max-width: calc(var(--text-max) + var(--card-padding) * 2);
  margin: 0 auto;
}

.case-next-label {
  padding: 0 var(--card-padding);
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 600;
  line-height: 19px;
  letter-spacing: -0.03px;
  color: var(--white-50);
}

/* Card padding = image-card padding, so the title lines up with the text column
   and the preview lines up with every screenshot above it */
.case-next .work-card {
  padding: var(--card-padding);
}

.case-next .work-card--flush {
  padding-bottom: 0;
}

.case-next .work-card--flush .work-media {
  margin: auto calc(var(--card-padding) * -1) 0;
}

.case-end .read-contact {
  margin-top: 64px;
}

@media (max-width: 1200px) {

  /* No header guideline any more — centre the column on tablet as well */
  .case-v2 .text-block,
  .case-v2 .image-with-caption,
  .case-v2 .slider-container {
    margin-left: auto;
    margin-right: auto;
  }

  .case-v2 .slider-container { width: 100%; }
  .case-v2 .slider-container--hero { max-width: none; }
  .case-v2 .image-with-caption--wide { max-width: 100%; }
}

@media (max-width: 900px) {
  .case-v2 .case-study { padding-top: 16px; }
  .case-v2 .case-study > .hl-navbar { margin-bottom: 40px; }
}

@media (max-width: 768px) {
  .case-end .read-contact { margin-top: 48px; }
}

/* =====================================================================
   Media frames in case studies — same rule as the Playground tiles:
   one surface, one radius, uniform padding (40px desktop = 5% of the 792px
   column, 16px on mobile), media never cropped.
   ===================================================================== */
.case-v2 .image-card,
.case-v2 .phone-grid-card {
  background: var(--frame-bg);
  border-radius: var(--frame-radius);
}

/* Phone screens used to float on the page without a frame */
.case-v2 .phone-grid {
  row-gap: 16px;
}

/* Sliders: cards in a row share a height — shorter media is fitted, not cropped */
.case-v2 .slider-card img {
  object-fit: contain;
}

@media (hover: hover) and (pointer: fine) {
  .case-v2 .zoom-card {
    transition: background-color 0.4s ease;
  }
  .case-v2 .zoom-card:hover {
    background: var(--frame-bg-hover);
  }
}

/* Tablet stack: frames keep their radius, with room between them */
@media (max-width: 1200px) {
  .case-v2 .phone-grid-card { border-radius: var(--frame-radius); }
  .case-v2 .phone-grid { row-gap: 8px; }
  .case-v2 .slider-track { gap: 8px; }
}

/* Mobile: rounded frames inside the 16px page gutter (same as the home page),
   instead of edge-to-edge */
@media (max-width: 768px) {
  .case-v2 .image-card,
  .case-v2 .slider-card,
  .case-v2 .phone-grid-card {
    border-radius: var(--frame-radius);
  }

  .case-v2 .image-with-caption,
  .case-v2 .slider-container,
  .case-v2 .phone-grid,
  .case-next {
    padding-left: var(--mobile-pad);
    padding-right: var(--mobile-pad);
  }

  /* captions and labels line up with the text column, not the frame's inside */
  .case-v2 .image-with-caption > .image-caption,
  .case-v2 .image-with-caption--wide .text-block,
  .case-next-label {
    padding-left: 0;
    padding-right: 0;
  }
}

/* =====================================================================
   Case layout — the home grid (sidebar column + content column), so the
   capsule sits in exactly the same spot as on the home page and stays put
   when you open a case. The sidebar column holds the table of contents.
   ===================================================================== */
.case-aside { display: none; }

@media (min-width: 901px) {
  .case-v2 {
    --main-pl: 48px;          /* = .hl-main left padding */
  }

  .case-layout {
    display: grid;
    grid-template-columns: var(--aside-w) minmax(0, 1fr);
    max-width: 1680px;
    margin: 0 auto;
  }

  .case-v2 .case-layout > .case-study {
    min-width: 0;
    max-width: none;
    margin: 0;
    padding: var(--gutter) var(--gutter) 0 var(--main-pl);
    container-type: inline-size; /* sliders measure the content column with cqw */
  }

  .case-aside {
    display: block;
    align-self: start;
    position: sticky;
    top: 0;
    max-height: 100vh;
    max-height: 100dvh;
    padding: var(--gutter) 40px 32px var(--gutter);
    overflow-y: auto;
    scrollbar-width: none;
  }

  .case-aside::-webkit-scrollbar { display: none; }

}

@media (min-width: 901px) and (max-width: 1200px) {
  .case-v2 { --main-pl: 32px; }
  .case-aside { padding: var(--gutter) 32px 28px var(--gutter); }
}

/* Desktop sliders: run from the sidebar edge to the page edge (not the whole viewport),
   first card's screenshot on the text guideline, last card ending on the column edge */
@media (min-width: 1201px) {
  .case-v2 .case-layout .slider-container {
    margin-left: calc(var(--main-pl) * -1);
    margin-right: calc(var(--gutter) * -1);
    width: auto;
    padding-left: calc(var(--main-pl) + max(0px, (100cqw - var(--text-max)) / 2 - var(--card-padding)));
  }

  .case-v2 .case-layout .slider-track {
    padding-right: calc(var(--gutter) + max(0px, (100cqw - var(--text-max)) / 2 - var(--card-padding)));
  }

  /* Hero: starts on the content column edge, like the work cards on the home page */
  .case-v2 .case-layout .slider-container--hero { padding-left: var(--main-pl); }
  .case-v2 .case-layout .slider-container--hero .slider-track { padding-right: var(--gutter); }

  /* Row geometry, measured on the content column (cqw):
     --col-off  where the 792px column starts (= first card's left edge)
     --card-w   a full card, narrowed when needed so the next one always peeks in ~120px
     --wide-w   the same for wide rows, which start on the content edge */
  .case-v2 .case-layout .slider-section {
    --col-off: max(0px, (100cqw - var(--text-max)) / 2 - var(--card-padding));
    --card-w: min(calc(var(--text-max) + var(--card-padding) * 2), 100cqw - var(--col-off) + var(--gutter) - 132px);
    --wide-w: min(1160px, 100cqw + var(--gutter) - 132px);
  }

  /* Only full-width cards shrink; narrow / custom-width cards keep their size */
  .case-v2 .case-layout .slider-container:not(.slider-container--hero)
    .slider-card:not(.slider-card--narrow):not(.slider-card--search):not([style*="width"]) {
    width: var(--card-w);
  }

  .case-v2 .case-layout .slider-container--hero .slider-card--wide {
    width: var(--wide-w);
  }

  /* Prev / next + counter under the slider, on the screenshot's edges of a full card:
     counter on its left edge, arrows end on its right edge */
  .slider-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: var(--card-w);
    margin: 16px 0 0 var(--col-off);
    padding: 0 var(--card-padding);
  }

  .slider-nav[hidden] { display: none; }

  .slider-nav--wide {
    width: var(--wide-w);
    margin-left: 0;
  }

  .slider-nav + .text-block { margin-top: 0; }

  .slider-count {
    font-size: 15px;
    font-weight: 400;
    line-height: 23px;
    letter-spacing: -0.03px;
    color: var(--white-50);
    font-variant-numeric: tabular-nums;
  }

  .slider-arrows {
    display: flex;
    gap: 8px;
  }

  .slider-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    color: var(--white-70);
    cursor: pointer;
    transition: background-color 0.25s ease, color 0.25s ease, opacity 0.25s ease, transform 0.3s var(--ease-spring);
  }

  .slider-arrow:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.1);
    color: var(--white-90);
  }

  .slider-arrow:active:not(:disabled) {
    transform: scale(0.92);
    transition-duration: 0.12s;
  }

  .slider-arrow:disabled {
    opacity: 0.35;
    cursor: default;
  }

  .slider-arrow:focus-visible { border-radius: 50%; }

  /* One-time hint: the row glides a little to the left and settles back */
  .slider-track.is-nudging {
    animation: slider-nudge 1.4s var(--ease-out);
  }

  @keyframes slider-nudge {
    0%   { transform: none; }
    35%  { transform: translateX(-72px); }
    100% { transform: none; }
  }
}

.slider-nav { display: none; }
@media (min-width: 1201px) {
  .slider-nav { display: flex; }
}

/* ----- Table of contents -----
   Same language as the capsule: Body S Semibold tabs (clickable), 52% at rest,
   white when hovered or current; the current one sits on a sliding pill that
   hugs its text. Rows are 36px like the capsule tabs, and the first one shares its line. */
.case-toc {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding-top: 4px;
}

.case-toc-pill {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 36px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  pointer-events: none;
  opacity: 0;
  transition: transform 0.5s var(--ease-out), width 0.5s var(--ease-out),
              height 0.5s var(--ease-out), opacity 0.25s ease;
}

.case-toc.is-ready .case-toc-pill { opacity: 1; }
.case-toc.no-motion .case-toc-pill { transition: none; }

.case-toc-link {
  position: relative;
  z-index: 1;
  display: block;
  max-width: 100%;
  padding: 8.5px 12px;
  border-radius: 18px;
  font-size: 15px;
  font-weight: 600;
  line-height: 19px;
  letter-spacing: -0.03px;
  color: var(--white-50);
  transition: color 0.25s ease;
  -webkit-tap-highlight-color: transparent;
}

.case-toc-link--sub {
  margin-left: 16px;
  max-width: calc(100% - 16px);
}

.case-toc-link:hover,
.case-toc-link.is-active {
  color: var(--white-90);
}

.case-toc-link:focus-visible { outline-offset: 0; }

/* Headings land just below the floating capsule */
.case-v2 [data-toc] {
  scroll-margin-top: calc(var(--nav-top) + var(--nav-h) + 24px);
}

@media (min-width: 901px) {
  .case-v2 [data-toc] {
    scroll-margin-top: calc(var(--nav-top) + var(--nav-h) + 40px);
  }
}

/* ----- Mobile: current section in a floating capsule at the bottom (thumb reach);
   tapping it opens the full list upwards ----- */
.toc-m { display: none; }

@media (max-width: 900px) {
  .toc-m { display: block; }

  .toc-m-btn {
    position: fixed;
    z-index: 46;
    left: 50%;
    bottom: calc(16px + env(safe-area-inset-bottom));
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: calc(100vw - 32px);
    height: var(--nav-h);
    padding: 0 14px 0 18px;
    border: 0;
    border-radius: 999px;
    background: var(--glass-stuck);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08),
                0 12px 32px -12px rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(12px) saturate(160%);
    -webkit-backdrop-filter: blur(12px) saturate(160%);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    line-height: 19px;
    letter-spacing: -0.03px;
    color: var(--white-90);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, 16px);
    transition: opacity 0.35s ease, transform 0.5s var(--ease-out), scale 0.3s var(--ease-out);
  }

  .toc-m.is-shown .toc-m-btn {
    opacity: 1;
    pointer-events: auto;
    transform: translate(-50%, 0);
  }

  .toc-m-btn:active { scale: 0.96; transition-duration: 0.12s; }
  .toc-m-btn:focus-visible { border-radius: 999px; }

  .toc-m-label {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  .toc-m-chevron {
    flex: none;
    color: var(--white-50);
    transition: transform 0.4s var(--ease-out);
  }

  .toc-m.is-open .toc-m-chevron { transform: rotate(180deg); }

  .toc-m-backdrop {
    position: fixed;
    z-index: 45;
    inset: 0;
    background: rgba(6, 6, 7, 0.6);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }

  .toc-m-panel {
    position: fixed;
    z-index: 46;
    left: 16px;
    right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom) + var(--nav-h) + 8px);
    max-height: min(60vh, 520px);
    max-height: min(60dvh, 520px);
    padding: 4px 6px 6px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: 22px;
    background: var(--glass-stuck);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08),
                0 16px 40px -12px rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(12px) saturate(160%);
    -webkit-backdrop-filter: blur(12px) saturate(160%);
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px) scale(0.98);
    transform-origin: 50% 100%;
    transition: opacity 0.25s ease, transform 0.4s var(--ease-out), visibility 0s linear 0.4s;
  }

  .toc-m.is-open .toc-m-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  .toc-m.is-open .toc-m-panel {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 0.25s ease, transform 0.4s var(--ease-out), visibility 0s;
  }

  /* Rows a touch taller in the list — they're tap targets */
  .case-toc--sheet .case-toc-link { padding-top: 10.5px; padding-bottom: 10.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .case-toc-pill { transition: opacity 0.25s ease; }
  .toc-m-btn, .toc-m-panel { transition-property: opacity, visibility; }
}

/* =====================================================================
   404 — reading-page shell, message centred in the space under the capsule
   ===================================================================== */
.err {
  min-height: calc(100vh - var(--gutter) - var(--nav-h) - 64px - 96px);
  min-height: calc(100dvh - var(--gutter) - var(--nav-h) - 64px - 96px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.err-code {
  margin-bottom: 16px;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  letter-spacing: 0;
  color: var(--green);
  font-variant-numeric: tabular-nums;
}

.err-actions {
  margin-top: 24px;
}
