:root {
  --chrome: #000;
  --ink: #fff;
  --ink-dim: rgba(255, 255, 255, 0.62);
  --track: rgba(255, 255, 255, 0.22);
  --radius: 18px;
  --card-gap: 8px;       /* gap between a card and its nested tile: Projects and Contact use the same value */
  --bio-size: 16px;      /* bio text and the CV link share this size */
  --ease: cubic-bezier(0.2, 0, 0, 1);
}

* { box-sizing: border-box; margin: 0; }

html, body { height: 100%; }

body {
  font-family: "Google Sans", -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  color: var(--ink);
  background: #e9dfd2;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Soft warm/blue wallpaper, in the spirit of a macOS desktop picture */
.wallpaper {
  position: fixed;
  inset: -10%;
  background:
    radial-gradient(60% 55% at 12% 88%, #2f6fe0 0%, rgba(47, 111, 224, 0) 70%),
    radial-gradient(50% 50% at 88% 12%, #f3b24c 0%, rgba(243, 178, 76, 0) 70%),
    radial-gradient(45% 50% at 42% 100%, #ee7a36 0%, rgba(238, 122, 54, 0) 72%),
    radial-gradient(45% 55% at 92% 95%, #fbe6c4 0%, rgba(251, 230, 196, 0) 75%),
    radial-gradient(55% 55% at 20% 15%, #f6d9a0 0%, rgba(246, 217, 160, 0) 70%),
    #f0a64a;
  filter: blur(30px) saturate(1.05);
}

.stage {
  position: relative;
  height: 100%;
  display: grid;
  place-items: center;
  padding: clamp(12px, 3vw, 40px);
}

.main {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: grid;
  place-items: center;
}

.frame {
  --pad: clamp(12px, 3vw, 40px);
  --navw: 300px;
  --head: 44px;
  --bar: 80px;   /* real height of the controls under the page: 14 + 10 + 6 + 4 + 6 + 40 */
  --gap: var(--pad);   /* same spacing as the page edges */
  width: 100%;
  display: flex;
  justify-content: flex-start;   /* left gap = --pad, the same as the top and bottom gaps */
  align-items: flex-end;   /* card sits on the viewer's bottom edge, only as tall as its content */
  gap: var(--gap);
}

/* Projects card: same structure as the viewer, a black tile holding a nested inner tile */
/* Right-hand area, as tall as the viewer and starting one gap to its right:
   the bio spans all the free width at the top, the cards sit beside the viewer at the bottom */
.side {
  flex: 1 1 var(--navw);
  min-width: var(--navw);
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--gap);
  position: relative;
}
.side-bottom {
  width: 100%;
  display: flex;
  /* wrap-reverse: if the contact card truly can't fit beside the projects card it goes ON TOP of it.
     (cross axis is flipped, so flex-start = the bottom edge) */
  flex-wrap: wrap-reverse;
  justify-content: space-between;   /* beside the projects card, contact is flush with the right edge */
  align-items: flex-start;
  gap: calc(var(--gap) / 2);   /* half the usual spacing between the projects and contact cards, side by side or stacked */
}
/* The contact card squeezes down to its content's minimum (the header gap and paddings are the slack)
   so it fits beside the projects card whenever possible, and grows back up to 175px when there is room. */
.side-bottom .contact.full { flex: 1 1 0; width: auto; max-width: none; }   /* fills all the width it is given */
/* Tall window where the right-hand column would be taller than the viewer: JS adds .bio-top to .stage.
   The bio moves to the top-left corner (same padding as the top and left edges); the viewer and the cards
   sit together on the bottom edge. Desktop only. */
@media (min-width: 901px) {
  .stage.bio-top .main { place-items: end start; }
  .stage.bio-top .side { justify-content: flex-end; }
  .stage.bio-top .bio {
    position: fixed;
    top: var(--pad);
    left: var(--pad);
    width: min(760px, calc(100vw - 2 * var(--pad)));
  }
}
/* Bio: plain text straight on the wallpaper, no card */
.bio-title {
  margin-bottom: 10px;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: #1b130a;
}
.bio p {
  font-size: var(--bio-size);
  line-height: 1.35;
  color: rgba(27, 19, 10, 0.78);
  text-wrap: pretty;
}
/* Contact card */
.contact {
  flex: 0 0 auto;
  width: fit-content;
  border-radius: var(--radius);
  background: var(--chrome);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.08) inset,
    0 30px 80px rgba(40, 20, 0, 0.35),
    0 8px 24px rgba(40, 20, 0, 0.25);
}
.social {
  width: 30px; height: 30px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  display: grid; place-items: center;
  font: inherit;
  font-size: 14px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.65);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.social:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.social.copy { font-size: 16px; }
.social svg {
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.social:has(svg) { color: #fff; }

/* full: title row + nested tile with the number and email */
.contact.full {
  --k: 1;                                 /* 0 = crushed to the tightest it can be, 1 = comfortable (JS sets it from the room beside the projects card) */
  --e: 0;                                 /* 0..1 = extra room beyond comfortable: spacing grows further */
  --cp: var(--card-gap);                  /* same gap as the projects card */
  padding: 0 var(--cp) var(--cp);
}
.contact-head {
  height: calc(34px + 10px * var(--k) + 6px * var(--e));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(4px * var(--k));
  padding: 0 calc(1px + 5px * var(--k)) 0 calc(3px + 7px * var(--k));
}
.contact-head .index-title { font-size: calc(11px + 4px * var(--k)); }
.contact-head .social {
  width: calc(20px + 8px * var(--k));
  height: calc(20px + 8px * var(--k));
  font-size: calc(11px + 3px * var(--k));
}
.socials { display: flex; gap: 1px; }
.contact-tile {
  padding: calc(1px + 3px * var(--k) + 4px * var(--e));
  border-radius: calc(var(--radius) - var(--cp));   /* concentric with the card, whatever its padding is */
  background: #1a1a1c;
  display: grid;
  gap: 1px;
}
.copy-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: calc(var(--radius) - 14px);
  background: rgba(255, 255, 255, 0);
  color: rgba(255, 255, 255, 0.72);
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}
.copy-row:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.copy-row i { flex: none; font-size: 12px; opacity: 0.55; }
/* the number and email are 📱 and 📧 buttons (still tap-to-copy), on every screen size */
.contact.full .copy-text, .contact.full .copy-row i { display: none; }
.copy-emoji { display: block; font-size: calc(14px + 4px * var(--k) + 3px * var(--e)); line-height: 1; }
.contact-tile { display: flex; justify-content: center; gap: calc(1px + 2px * var(--k) + 8px * var(--e)); }   /* full-width tile, emoji together in the middle */
.copy-row { flex: 1 1 0; width: auto; justify-content: center;   /* each button is half of the tile, so its hover fills that half */
  padding: calc(5px + 7px * var(--k) + 8px * var(--e)) calc(2px + 5px * var(--k) + 8px * var(--e)); }   /* vertical padding is larger: it costs no width */
/* Stacked on top of the projects card (JS adds .stacked to .side-bottom when there is no room beside it):
   as wide as the projects card, and with the room it gets, the full number and email as text */
/* stacked: projects on top, contact underneath at the very bottom (plain wrap puts the later item below) */
.side-bottom.stacked { flex-wrap: wrap; }
.side-bottom.stacked .contact.full { flex: 0 0 auto; width: max-content; min-width: var(--navw); max-width: none; }
.side-bottom.stacked .contact.full .copy-emoji { display: none; }
.side-bottom.stacked .contact.full .copy-text,
.side-bottom.stacked .contact.full .copy-row i { display: inline; }
.side-bottom.stacked .contact.full .contact-tile { display: grid; justify-content: stretch; gap: 1px; padding: 6px; }
.side-bottom.stacked .contact.full .copy-row { flex: none; width: 100%; justify-content: space-between; gap: 16px; padding: 9px 12px; }
.side-bottom.stacked .contact.full .copy-text { white-space: nowrap; }
.copy-row.copied { color: #fff; }
.copy-row.copied i { opacity: 1; }

.bio-links {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 14px;
}
.cv {
  font-size: var(--bio-size);
  font-weight: 600;
  color: #1b130a;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
  transition: opacity 0.2s;
}
.cv:hover { opacity: 0.65; }
.cv:focus-visible { outline: 2px solid #1b130a; outline-offset: 4px; border-radius: 2px; }
.bio-top { margin-bottom: 6px; }
.bio-top .wave { display: block; font-size: 30px; line-height: 1.2; }

.index {
  flex: 0 0 auto;
  width: fit-content;       /* exactly as wide as its content needs, never truncated */
  padding: 0 var(--card-gap) var(--card-gap);
  border-radius: var(--radius);
  background: var(--chrome);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.08) inset,
    0 30px 80px rgba(40, 20, 0, 0.35),
    0 8px 24px rgba(40, 20, 0, 0.25);
}
/* header row, same height as the viewer's traffic-light row */
.index-head {
  height: var(--head);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px 0 10px;
}
.index-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  color: #fff;
}
.index-toggle {
  width: 26px; height: 26px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.index-toggle:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.index-toggle svg {
  width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.index-toggle .v {
  transform-origin: 12px 12px;
  transform: scaleY(0);
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}
.index.collapsed .index-toggle .v { transform: scaleY(1); }

/* collapsing: the body animates to zero height, leaving just the title bar */
.index { transition: padding-bottom 0.4s cubic-bezier(0.32, 0.72, 0, 1); }
.index-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.4s cubic-bezier(0.32, 0.72, 0, 1);
}
.index-in { min-height: 0; overflow: hidden; }
.index.collapsed { padding-bottom: 0; }
.index.collapsed .index-body { grid-template-rows: 0fr; }

/* nested tile, like the page inside the viewer */
.index-tile {
  position: relative;
  /* top/bottom: enough room that the selected pill on the first or last row sits as far from the rail's end
     as it does from the rail's sides: (30 - 8) / 2 = 11px */
  --pill: 18px;               /* height of the selected pill */
  padding: calc(var(--pill) / 2 + 0.25px) 6px;   /* = 6 (rail inset) + 11 (side gap) + pill/2 - half a row (16.75) */
  border-radius: calc(var(--radius) - var(--card-gap));   /* concentric: outer radius minus the gap */
  background: #1a1a1c;
  transition: opacity 0.25s ease;
}
.index.collapsed .index-tile { opacity: 0; }
.index ol {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 1px;
}
.index li { position: relative; }
.index a {
  display: block;
  margin-right: 36px;           /* hover tile stops short of the 30px dot rail, leaving a 6px gap */
  padding: 8px 8px 8px 12px;
  border-radius: calc(var(--radius) - 14px);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.72);
  background: rgba(255, 255, 255, 0);
  text-decoration: none;
  transition: color 0.25s ease, font-weight 0.25s ease, background-color 0.25s ease;
  -webkit-tap-highlight-color: transparent;
}
/* invisible bold copy of the title reserves its widest width, so selecting a project never resizes the card */
.index a::before {
  content: attr(data-t);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
  pointer-events: none;
}
.index a:hover { color: #fff; background: rgba(255, 255, 255, 0.07); }
.index a.active { color: #fff; font-weight: 700; }

/* One dot per project on the right; the current one stretches into a pill */
.index li::after {
  content: "";
  position: absolute;
  right: 11px;            /* centered in the 30px rail */
  top: 50%;
  width: 8px; height: 8px;
  border-radius: 4px;
  background: #fff;
  opacity: 0.85;
  translate: 0 -50%;
  transition: height 0.45s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.3s ease;
  pointer-events: none;
  z-index: 3;
}
/* rail behind the dots: inset 6px inside the tile, so its radius is the tile's minus 6px */
.dotrail {
  position: absolute;
  top: 6px; bottom: 6px; right: 6px;
  width: 30px;
  border-radius: calc(var(--radius) - 14px);
  background: rgba(255, 255, 255, 0);   /* invisible until hovered or dragged */
  cursor: grab;
  touch-action: none;
  user-select: none;
  z-index: 2;
  transition: background 0.2s ease;
}
.dotrail:hover, .dotrail.dragging { background: rgba(255, 255, 255, 0.12); }
.dotrail.dragging { cursor: grabbing; }
.index li:has(> a.active)::after { height: var(--pill); opacity: 1; }
.index a:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

/* The window sizes itself to the largest A3-landscape page that fits */
.window {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 0 12px;
  flex: 0 1 auto;
  width: min(calc(100% - var(--navw) - var(--gap)), calc((100vh - 2 * var(--pad) - var(--head) - var(--bar)) * 1.4142 + 24px));
  background: var(--chrome);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.08) inset,
    0 30px 80px rgba(40, 20, 0, 0.35),
    0 8px 24px rgba(40, 20, 0, 0.25);
}

.chrome {
  height: var(--head);
  display: flex;
  align-items: center;
  padding: 0 18px;
  position: relative;
  grid-column: 1 / -1;
  margin: 0 -12px;
}

.lights { display: flex; gap: 8px; z-index: 1; }

.light {
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.light.red { background: #ff5f57; }
.light.yellow { background: #febc2e; }
.light.green { background: #28c840; }
.light:hover { filter: brightness(1.12); }

.title {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 12.5px;
  color: var(--ink-dim);
  letter-spacing: 0.01em;
  pointer-events: none;
}

.screen {
  position: relative;
  grid-column: 1;
  grid-row: 2;
  aspect-ratio: 297 / 210;
  border-radius: calc(var(--radius) - 12px);
  overflow: hidden;
  background: #111;
  outline: none;
  user-select: none;
  touch-action: pan-y;
}

.page {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  background: #fff;
}
.page.swap { animation: pageIn 0.28s var(--ease); }
@keyframes pageIn { from { opacity: 0.35; } to { opacity: 1; } }

.nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 0;
  display: grid; place-items: center;
  color: #fff;
  background: rgba(0, 0, 0, 0.42);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s, scale 0.15s var(--ease);
}
.nav.prev { left: 14px; }
.nav.next { right: 14px; }
.screen:hover .nav { opacity: 1; }
.nav:active { scale: 0.94; }
.nav[disabled] { opacity: 0 !important; pointer-events: none; }
.nav svg, .icon svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

.controls { grid-column: 1; grid-row: 3; padding: 14px 12px 10px; }

.scrub {
  position: relative;
  height: 4px;
  background: var(--track);
  border-radius: 2px;
  cursor: pointer;
  margin: 6px 0 0;
  outline: none;
}
/* bigger invisible hit area */
.scrub::before { content: ""; position: absolute; inset: -12px 0; }
.fill {
  position: relative;
  height: 100%;
  width: 0;
  background: #fff;
  border-radius: 2px;
  transition: width 0.25s var(--ease);
}
.fill::after {
  content: "";
  position: absolute;
  top: 50%; right: -6px;
  width: 12px; height: 12px;
  margin-top: -6px;
  border-radius: 50%;
  background: #fff;
}
.scrub:focus-visible { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.4); }
.tip {
  position: absolute;
  bottom: 16px;
  translate: -50% 0;
  padding: 3px 7px;
  font-size: 11px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.92);
  color: #000;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s;
  font-variant-numeric: tabular-nums;
}
.scrub:hover .tip { opacity: 1; }

.row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 40px;
  margin-top: 6px;
}
.left, .right { display: flex; gap: 4px; align-items: center; }
.right { justify-content: flex-end; }

.count {
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.icon {
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: #fff;
  display: grid; place-items: center;
  cursor: pointer;
  transition: background 0.15s;
}
.icon:hover { background: rgba(255, 255, 255, 0.12); }
.icon:active { background: rgba(255, 255, 255, 0.2); }
.icon[disabled] { color: rgba(255, 255, 255, 0.3); pointer-events: none; }
button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Overview: covers only the page area, so the control bar underneath stays usable */
.overview {
  position: absolute;
  inset: var(--head) 12px var(--bar) 12px;
  border-radius: calc(var(--radius) - 12px);
  background: rgba(14, 14, 15, 0.97);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  overflow: hidden;
  z-index: 5;
}
.overview[hidden] { display: none; }
/* the grid is the scroller; its native scrollbar is hidden in favour of the pill below */
#grid {
  height: 100%;
  overflow-y: auto;
  padding: 18px 34px 24px 20px;
  scrollbar-width: none;
}
#grid::-webkit-scrollbar { display: none; }

/* Custom scrollbar: a pill track holding a pill handle, 2px gap all round */
.scrolltrack {
  position: absolute;
  top: 12px; bottom: 12px; right: 8px;
  width: 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  z-index: 2;
}
.scrolltrack[hidden] { display: none; }
.scrollthumb {
  position: absolute;
  top: 0; left: 2px; right: 2px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.38);
  cursor: grab;
  touch-action: none;
  transition: background-color 0.2s;
}
.scrollthumb:hover, .scrolltrack.dragging .scrollthumb { background: rgba(255, 255, 255, 0.65); }
.scrolltrack.dragging .scrollthumb { cursor: grabbing; }
.group + .group { margin-top: 26px; }
.group-title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  color: #fff;
}
.group-title span { font-size: 11.5px; font-weight: 500; color: rgba(255, 255, 255, 0.4); }
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 14px;
}
.thumb {
  position: relative;
  padding: 0;
  border: 0;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  background: #222;
  aspect-ratio: 297 / 210;
  opacity: 0.8;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: outline-color 0.15s, opacity 0.2s ease, scale 0.15s var(--ease);
}
.thumb:hover, .thumb.current { opacity: 1; }
.thumb:hover { scale: 1.02; }
.thumb.current { outline-color: #fff; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb span {
  position: absolute; left: 6px; bottom: 6px;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* Fullscreen: drop the wallpaper chrome, fill the display */
.window:fullscreen { width: 100%; height: 100%; padding: 0; border-radius: 0; display: flex; flex-direction: column; box-shadow: none; }
.window:fullscreen .screen { flex: 1; aspect-ratio: auto; margin: 0; border-radius: 0; }
.window:fullscreen .chrome { display: none; }
.window:fullscreen .controls { padding: 14px 24px 10px; }
.window:fullscreen .overview { inset: 0 0 var(--bar) 0; border-radius: 0; }
.window:fullscreen, .window:fullscreen .screen { background: #000; }
.window:fullscreen .page { background: transparent; }
.window::backdrop { background: #000; }

/* Mobile / small screens: bio on top at full width, the viewer in the middle,
   the projects card at the bottom-left and the contact card at the bottom-right */
@media (max-width: 900px) {
  body { overflow-y: auto; }
  .stage { height: auto; min-height: 100%; display: block; }
  .main { height: auto; display: block; }
  .frame {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    gap: var(--pad);
    min-height: calc(100dvh - 2 * var(--pad));
    align-items: start;
  }
  .side { display: contents; }
  .bio { grid-row: 1; margin-bottom: calc(120px - var(--pad)); }   /* 120px in total between the bio and the viewer (the grid gap already supplies --pad) */
  .window { grid-row: 2; width: 100%; }
  .side-bottom {
    grid-row: 3;
    align-self: end;
    width: 100%;
    display: flex;
    flex-wrap: wrap-reverse;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--pad);   /* small screens: the space between the projects and contact cards equals the edge padding, side by side or stacked */
  }
  /* trimmed gaps so the projects bar and the full card fit side by side on a ~390px phone */
  .copy-row { gap: 10px; }
  .index-head { gap: 12px; }
  /* collapsed on a small screen: shrink to just the title bar */
  .index.collapsed .index-body { display: none; }
}

@media (max-width: 640px) {
  :root { --card-gap: 6px; }
  .frame { --head: 36px; --bar: 92px; --gap: 8px; }
  .window { border-radius: var(--radius); width: 100%; }
  .window { padding: 0 8px; }
  .chrome { margin: 0 -8px; }
  .controls { padding: 10px 6px 6px; }
  .count { font-size: 15px; }
  :root { --bio-size: 15px; }
  .bio-title { font-size: 26px; }
  /* a little tighter so the projects bar and the full contact card share one row at ~390px */
  .index-title { font-size: 13px; }
  /* compact cards so projects + contact sit side by side down to ~390px wide */
  .index a { padding: 8px 4px 8px 10px; font-size: 12px; margin-right: 32px; }
  .bio-top .wave { font-size: 26px; }
  .nav { display: none; }
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .overview { inset: var(--head) 8px var(--bar) 8px; }
  #grid { padding: 14px 28px 18px 12px; }
  .title { font-size: 11.5px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
