/* John Kevin Espino — single-page CV site. Vanilla CSS. */
/* Artifex Hand CF, self-hosted (Latin subset, WOFF2). */
@font-face {
  font-family: 'Artifex Hand CF';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/ArtifexHandCF-Regular.woff2') format('woff2');
}

@font-face {
  font-family: 'Artifex Hand CF';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/ArtifexHandCF-RegularItalic.woff2') format('woff2');
}

@font-face {
  font-family: 'Artifex Hand CF';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/ArtifexHandCF-Bold.woff2') format('woff2');
}

@font-face {
  font-family: 'Artifex Hand CF';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/ArtifexHandCF-BoldItalic.woff2') format('woff2');
}

:root {
  --accent: #017100;
  --ink: #1b1b1b;
  --muted: #5b5b5b;
  --faint: #767676;
  --rule: #cfd6cb;
  --panel: #eaeee5;
  --bg: #f5f6f0;
  --font: 'Artifex Hand CF', 'Artifex Hand', ui-rounded, system-ui, sans-serif;
  --measure: 56rem;
  --r-s: 8px;
  /* small controls: nav items, toggles */
  --r: 12px;
  /* base radius: buttons, inputs, panels, logos */
  --r-l: 16px;
  /* larger surfaces: dialog, cards, menus */
}

/* Dark theme: used when the visitor picks it, or when their system prefers dark and they haven't chosen. */
:root[data-theme='dark'] {
  --accent: #5fc15a;
  --ink: #ecf0ea;
  --muted: #aeb5ab;
  --faint: #8d958a;
  --rule: #2f372d;
  --panel: #171d16;
  --bg: #0f130f;
  color-scheme: dark;
}

:root[data-theme='light'] {
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --accent: #5fc15a;
    --ink: #ecf0ea;
    --muted: #aeb5ab;
    --faint: #8d958a;
    --rule: #2f372d;
    --panel: #171d16;
    --bg: #0f130f;
    color-scheme: dark;
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 1.5rem;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  text-decoration-thickness: 2px;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

a:focus-visible {
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--accent);
  color: #fff;
  padding: 0.5rem 1rem;
  z-index: 20;
}

.skip:focus {
  left: 0;
}

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* nav: links left, theme + CTA right at the top; a centered, hugging, fully rounded pill (with photo) once you scroll */
.float {
  position: fixed;
  top: 0.9rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  width: min(calc(var(--measure) - 3rem), calc(100vw - 1.2rem));
  display: flex;
  justify-content: center;
  pointer-events: none;
}

.pill {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0.35rem 0;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  transition:
    width 0.4s ease,
    padding 0.4s ease,
    background 0.25s ease,
    border-color 0.25s ease,
    box-shadow 0.25s ease;
}

.float.scrolled .pill {
  width: var(--hugw, auto);
  padding: 0.35rem;
  background: color-mix(in srgb, var(--bg) 96%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-color: var(--rule);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.08);
}

@media (prefers-reduced-motion: reduce) {
  .pill,
  .navphoto,
  .navcta {
    transition: none !important;
  }
}

.navphoto {
  display: block;
  flex: none;
  width: 0;
  height: 2.1rem;
  margin-right: 0;
  border-radius: 50%;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  border: 0 solid var(--rule);
  transition:
    width 0.3s ease,
    margin 0.3s ease,
    opacity 0.25s ease,
    visibility 0s linear 0.3s;
}

.navphoto img {
  width: 2.1rem;
  height: 2.1rem;
  object-fit: cover;
  display: block;
}

.float.scrolled .navphoto {
  width: 2.1rem;
  margin-right: 0.5rem;
  opacity: 1;
  visibility: visible;
  border-width: 1px;
  transition:
    width 0.3s ease,
    margin 0.3s ease,
    opacity 0.25s ease,
    visibility 0s;
}

.navphoto:focus-visible {
  outline-offset: 2px;
}

.links {
  display: flex;
  gap: 0.2rem;
  list-style: none;
  margin: 0 auto 0 0;
  padding: 0;
  transition: margin 0.4s ease;
}

.float:not(.scrolled) .links {
  margin-left: -0.8rem;
}

.links > li > a,
.links .dl-trigger.navdl {
  display: inline-flex;
  align-items: center;
  height: 2.1rem;
  padding: 0 0.8rem;
  border-radius: 8px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.95rem;
  line-height: 1;
  transition:
    color 0.15s,
    background 0.15s;
}

.links > li > a:hover {
  color: var(--ink);
  background: var(--panel);
}

.links > li > a[aria-current='true'] {
  color: var(--accent);
  background: var(--panel);
}

.menu-btn {
  display: none;
  background: none;
  border: 0;
  color: var(--muted);
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 8px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin-right: auto;
}

.menu-btn:hover,
.menu-btn[aria-expanded='true'] {
  color: var(--ink);
  background: var(--panel);
}

.menu-btn svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

.actions {
  display: flex;
  align-items: center;
  margin-left: 2.2rem;
}

.navcta {
  display: inline-flex;
  align-items: center;
  height: 2.1rem;
  padding: 0 1rem;
  background: var(--accent);
  color: var(--bg);
  border: 1px solid var(--accent);
  border-radius: var(--r-s) 1.05rem 1.05rem var(--r-s);
  text-decoration: none;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  max-width: 12rem;
  margin-left: 0.6rem;
  transition:
    max-width 0.3s ease,
    padding 0.3s ease,
    margin 0.3s ease,
    border-width 0.3s ease,
    opacity 0.25s ease,
    visibility 0s;
}

.navcta:hover {
  opacity: 0.88;
}

/* revealed like the photo: grows in from nothing as the bar appears */
.float:not(.scrolled) .navcta {
  max-width: 0;
  padding: 0;
  margin-left: 0;
  border-width: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    max-width 0.3s ease,
    padding 0.3s ease,
    margin 0.3s ease,
    border-width 0.3s ease,
    opacity 0.25s ease,
    visibility 0s linear 0.3s;
}

.float.scrolled .navcta {
  border-radius: var(--r-s) 1.05rem 1.05rem var(--r-s);
  padding: 0 1.1rem 0 1rem;
}

/* theme switch: shows the active choice; expands to light / system / dark on hover or focus */
.themesw {
  position: relative;
  width: 2.1rem;
  height: 2.1rem;
  flex: none;
}

.themesw-in {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  height: 2.1rem;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--panel);
  z-index: 8;
  transition:
    background 0.15s,
    border-color 0.15s;
}

.themesw button {
  background: none;
  border: 0;
  color: var(--faint);
  width: 2.1rem;
  height: calc(2.1rem - 2px);
  margin: -1px 0;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex: none;
  overflow: hidden;
  max-width: 0;
  opacity: 0;
  pointer-events: none;
  transition:
    max-width 0.2s ease,
    opacity 0.15s;
}

.themesw button[aria-checked='true'] {
  max-width: 2.1rem;
  opacity: 1;
  pointer-events: auto;
  color: var(--ink);
}

.themesw svg {
  width: 1rem;
  height: 1rem;
  fill: currentColor;
  flex: none;
}

/* the "system" option shows a computer on desktop and a phone on touch / small screens */
.themesw .i-mobile {
  display: none;
}

@media (hover: none), (max-width: 720px) {
  .themesw .i-desk {
    display: none;
  }

  .themesw .i-mobile {
    display: block;
  }
}

/* The pill is a quiet grey. Green only shows up on the chosen option and on whatever you point at. */
.themesw-in {
  --pick: color-mix(in srgb, var(--accent) 14%, var(--panel));
}

.themesw.open .themesw-in,
.themesw:focus-within .themesw-in {
  background: var(--panel);
  border-color: var(--rule);
}

.themesw.open button,
.themesw:focus-within button {
  max-width: 2.1rem;
  opacity: 1;
  pointer-events: auto;
}

/* the chosen option: green icon, pale green circle (while the switch is open) */
.themesw.open button[aria-checked='true'],
.themesw:focus-within button[aria-checked='true'] {
  background: var(--pick);
  color: var(--accent);
}

/* an option you point at: only the icon turns green */
.themesw button:hover {
  color: var(--accent);
}

@media (hover: hover) {
  .themesw:hover .themesw-in {
    background: var(--panel);
    border-color: var(--rule);
  }

  .themesw:hover button {
    max-width: 2.1rem;
    opacity: 1;
    pointer-events: auto;
  }

  .themesw:hover button[aria-checked='true'] {
    background: var(--pick);
    color: var(--accent);
  }
}

/* hero */
.hero {
  padding: 7.5rem 0 0;
}

.hero {
  text-align: center;
}

.hero .top {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero h1 {
  margin: 1.5rem 0 0;
  font-weight: 400;
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
}

.tagline {
  margin: 0.7rem 0 0;
  font-size: clamp(1.1rem, 2.6vw, 1.35rem);
  color: var(--accent);
}

.photo {
  width: 5.5rem;
  height: 5.5rem;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: var(--panel);
  flex: none;
}

.divider {
  width: 24px;
  height: 1px;
  margin: 2.25rem auto 0;
  border: 0;
  background: var(--faint);
}

.intro {
  margin: 2.25rem auto 0;
  max-width: 40rem;
}

.intro .lede {
  display: block;
  font-size: clamp(1.05rem, 2.2vw, 1.2rem);
  line-height: 1.35;
  color: var(--ink);
}

.intro .rest {
  display: block;
  margin-top: 1.1rem;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--muted);
}

.cta {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  margin-top: 2.5rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  height: 2.7rem;
  padding: 0 1.15rem;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  font: inherit;
  font-size: 1rem;
  border-radius: var(--r);
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s,
    opacity 0.15s;
}

.btn:hover {
  background: var(--panel);
  border-color: var(--faint);
}

.btn.big {
  height: 3.2rem;
  padding: 0 1.8rem;
  font-size: 1.1rem;
}

.btn.solid {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.btn.solid:hover {
  background: var(--accent);
  border-color: var(--accent);
  opacity: 0.88;
}

.btn svg,
.dl-trigger svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

.dl-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  height: 3.2rem;
  padding: 0 0.55rem;
  background: none;
  border: 0;
  border-radius: var(--r);
  color: var(--muted);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

.dl-trigger:hover,
.dl-trigger[aria-expanded='true'] {
  background: var(--panel);
  color: var(--ink);
}

.dl-trigger .i-pdf {
  width: 1.3rem;
  height: 1.3rem;
}

.dl-trigger .i-chev,
.btn .i-chev {
  width: 0.7rem;
  height: 0.7rem;
  margin-left: 0.15rem;
  opacity: 0.7;
  transition: transform 0.15s;
}

.dl-trigger[aria-expanded='true'] .i-chev {
  transform: rotate(180deg);
}

.dl {
  position: relative;
}

.dl-menu {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 50%;
  transform: translateX(-50%);
  min-width: 17rem;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
  z-index: 5;
}

.dl-menu[hidden] {
  display: none;
}

.dl-head {
  padding: 0.5rem 0.7rem 0.3rem;
  font-size: 0.7rem;
  color: var(--faint);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.dl-menu a {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.5rem 0.7rem;
  border-radius: var(--r-s);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.98rem;
}

.dl-menu em {
  font-style: normal;
  color: var(--faint);
  font-size: 0.88rem;
  margin-left: 0.35rem;
}

.dl-menu small {
  color: var(--faint);
  font-size: 0.85rem;
  white-space: nowrap;
}

.dl-menu a:hover,
.dl-menu a:focus-visible {
  background: var(--panel);
}

.icons {
  display: flex;
  gap: 0.75rem;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border: 0;
  border-radius: var(--r);
  color: var(--accent);
  transition: background 0.15s;
}

.icon-btn:hover {
  background: var(--panel);
}

.icon-btn svg {
  width: 1.7rem;
  height: 1.7rem;
  fill: currentColor;
}

/* sections */
section {
  padding-top: 6rem;
}

.sec-title {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 0 0 1.25rem;
}

.sec-title h2 {
  margin: 0;
  font-weight: 400;
  font-size: 0.85rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.sec-title::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.skills {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
}

/* desktop: let the three equal columns run slightly wider than the text column so no bullet wraps */
@media (min-width: 62rem) {
  .skills {
    margin-inline: -3rem;
  }

  .skill li {
    white-space: nowrap;
  }
}

.skill {
  background: var(--panel);
  padding: 1rem 1rem 0.8rem;
  border-radius: var(--r);
}

.skill h3 {
  margin: 0 0 0.4rem;
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--accent);
}

ul.sq {
  list-style: none;
  margin: 0;
  padding: 0;
}

ul.sq li {
  position: relative;
  padding-left: 0.9rem;
  margin: 0.18rem 0;
}

ul.sq li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.28rem;
  height: 0.28rem;
  background: var(--accent);
}

.entry {
  padding-top: 2.75rem;
}

.entry:first-of-type {
  padding-top: 0;
}

.head {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  position: sticky;
  top: 3.85rem;
  z-index: 4;
  background: var(--bg);
  padding: 0.6rem 0 0.5rem;
}

.head::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 1.1rem;
  background: linear-gradient(transparent, var(--bg));
  pointer-events: none;
}

.head::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 0.7rem;
  background: linear-gradient(var(--bg), transparent);
  pointer-events: none;
}

@media (min-width: 62rem) {
  .head {
    display: block;
    box-shadow: -4.6rem 0 0 var(--bg);
  }

  .head::before {
    left: -4.6rem;
  }

  .head .logo {
    position: absolute;
    left: -3.9rem;
    top: 0.65rem;
  }
}

.head-main {
  flex: 1;
  min-width: 0;
}

.logo {
  position: relative;
  flex: none;
  width: 2.9rem;
  height: 2.9rem;
  border-radius: var(--r);
  border: 0;
  background: var(--panel);
  display: grid;
  place-items: center;
  overflow: hidden;
  color: var(--accent);
  font-size: 1.2rem;
}

.logo b {
  font-weight: 400;
}

.logo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.entry header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
}

.entry h3 {
  margin: 0;
  font-weight: 400;
  font-size: 1.05rem;
  line-height: 1.3;
}

.entry h3 .org {
  font-size: 1.35rem;
  color: var(--accent);
  margin-right: 0.5rem;
}

.entry h3 .org small {
  font-size: 0.95rem;
  color: var(--muted);
}

.dates {
  color: var(--muted);
  font-size: 0.95rem;
  white-space: nowrap;
}

.where {
  margin: 0.1rem 0 0;
  color: var(--muted);
  font-size: 0.98rem;
  display: flex;
  gap: 0.4rem;
  align-items: baseline;
}

.where svg {
  flex: none;
  width: 0.95rem;
  height: 0.95rem;
  margin: 0 -0.15rem;
  fill: currentColor;
  transform: translateY(0.15rem);
}

.where i,
.desc i {
  font-style: italic;
}

.desc {
  margin: 0.15rem 0 0;
  color: var(--muted);
  font-size: 0.98rem;
}

.ttl {
  display: inline;
}

.entry ul.sq {
  margin-top: 0.75rem;
}

.role {
  margin: 1.6rem 0 0.65rem;
  font-weight: 400;
  font-size: 1.22rem;
  line-height: 1.25;
  color: var(--ink);
}

.role span {
  margin-left: 0.6rem;
  color: var(--faint);
  font-size: 0.92rem;
}

/* timeline (dots and line under the logo) only at the desktop breakpoint, >=62rem (992px) */
.rolebox {
  --lx: -2.45rem;
  position: relative;
  padding: 0 0 0.6rem;
}

.rolebox::before,
.rolebox::after {
  display: none;
  content: '';
  position: absolute;
  left: var(--lx);
  transform: translateX(-50%);
}

.rolebox::before {
  top: 0.55rem;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--accent);
}

.rolebox::after {
  top: 1.4rem;
  bottom: -0.4rem;
  width: 2px;
  background: var(--rule);
}

@media (min-width: 62rem) {
  .rolebox::before,
  .rolebox::after {
    display: block;
  }
}

.rolebox:last-child::after {
  display: none;
}

.rolebox .role {
  margin-top: 0;
}

.rolebox + .rolebox {
  margin-top: 1rem;
}

.head + .rolebox {
  margin-top: 1.6rem;
}

.role + ul.sq {
  margin-top: 0;
}

.sub-edu {
  margin-top: 1rem;
}

/* contact */
.closing {
  padding-bottom: 5rem;
}

.closing-card {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: color-mix(in srgb, var(--accent) 9%, var(--bg));
  color: var(--ink);
  border-radius: var(--r-l);
  padding: 4rem 1.5rem 3.5rem;
  text-align: center;
}

.closing-card::before {
  content: '';
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  width: 34rem;
  height: 34rem;
  left: 50%;
  top: -22rem;
  transform: translateX(-50%);
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--accent) 22%, transparent),
    transparent
  );
}

/* keep the punchline together on one line */
.closing-card .keep {
  white-space: nowrap;
}

.closing-card h2 {
  margin: 0 auto;
  text-wrap: balance;
  max-width: 38rem;
  font-weight: 400;
  font-size: clamp(1.7rem, 4.4vw, 2.5rem);
  line-height: 1.1;
  letter-spacing: -0.015em;
}

.closing-card p {
  margin: 1.1rem auto 0;
  max-width: 30rem;
  font-size: 1.05rem;
  color: var(--muted);
}

.closing-cta {
  margin-top: 2.25rem;
}

/* social icons live in the footer, kept small and quiet */
footer .icons {
  gap: 0.25rem;
}

footer .icon-btn {
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-s);
  color: var(--faint);
  transition: background 0.15s, color 0.15s;
}

footer .icon-btn svg {
  width: 1.05rem;
  height: 1.05rem;
}

footer .icon-btn:hover {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

footer {
  padding: 0 0 2rem;
  color: var(--faint);
  font-size: 0.9rem;
}

.foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--rule);
  padding-top: 1.25rem;
}

.foot-r {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

.totop {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 999px;
  background: var(--panel); /* same fill as the theme switch up top */
  color: var(--faint);
  transition:
    background 0.15s,
    color 0.15s;
}

.totop:hover {
  background: color-mix(in srgb, var(--accent) 14%, var(--panel));
  color: var(--accent);
}

.totop svg {
  width: 0.8rem;
  height: 0.8rem;
  fill: currentColor;
}

/* reveal */
.js .reveal {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
}

.js .reveal.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

@media (max-width: 720px) {
  .menu-btn {
    display: inline-flex;
  }

  .float.scrolled .pill {
    width: 100%;
  }

  .actions {
    margin-left: 0.5rem;
  }

  .links {
    display: none;
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0;
    flex-direction: column;
    gap: 0;
    margin: 0;
    padding: 0.4rem;
    min-width: 12rem;
    background: var(--bg);
    border: 1px solid var(--rule);
    border-radius: var(--r-l);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  }

  .float.menu-open .links {
    display: flex;
    pointer-events: auto;
  }

  .links a {
    display: block;
    padding: 0.55rem 0.8rem;
    border-radius: var(--r-s);
    font-size: 1rem;
  }

  .links a:hover {
    background: var(--panel);
  }

  .navcta {
    padding: 0 0.85rem;
    font-size: 0.9rem;
  }

  .hero {
    padding-top: 6rem;
  }

  section {
    padding-top: 4.5rem;
  }

  .skills {
    grid-template-columns: 1fr;
  }

  .dates {
    white-space: normal;
  }

  .head {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 0.8rem;
    row-gap: 0.15rem;
    align-items: center;
  }

  .head-main,
  .head-main header,
  .head h3 {
    display: contents;
  }

  .head .logo {
    grid-column: 1;
    grid-row: 1;
    width: 2.6rem;
    height: 2.6rem;
  }

  .head .org {
    grid-column: 1/-1;
    grid-row: 1;
    margin: 0;
  }

  .head.has-logo .org {
    grid-column: 2;
  }

  .head .dates {
    grid-column: 1/-1;
    grid-row: 2;
    margin-top: 0.25rem;
  }

  .head .where {
    grid-column: 1/-1;
    grid-row: 3;
  }

  .head .desc {
    grid-column: 1/-1;
    grid-row: 4;
  }

  .float.scrolled .navphoto {
    margin-right: 0.5rem;
  }
}

@media print {
  .float,
  .cta,
  .skip,
  .dl {
    display: none;
  }

  :root {
    --accent: #017100;
    --ink: #1b1b1b;
    --muted: #5b5b5b;
    --faint: #767676;
    --rule: #cfd6cb;
    --panel: #f3f7f2;
    --bg: #fff;
  }

  body {
    font-size: 10pt;
    color: #000;
    background: #fff;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }

  .wrap {
    max-width: none;
    padding: 0;
  }

  .hero {
    padding: 0;
  }

  .skills {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .divider {
    display: none;
  }

  .dates {
    white-space: nowrap;
  }

  .divider {
    width: 24px;
    height: 1px;
    margin: 2.25rem auto 0;
    border: 0;
    background: var(--faint);
  }

  .intro {
    margin: 2.25rem auto 0;
    max-width: 40rem;
  }

  .intro .lede {
    display: block;
    font-size: clamp(1.35rem, 3.2vw, 1.75rem);
    line-height: 1.25;
    color: var(--ink);
  }

  .intro .rest {
    display: block;
    margin-top: 0.9rem;
    font-size: 1rem;
    line-height: 1.55;
    color: var(--muted);
  }

  .entry {
    padding-top: 1.1rem;
  }

  .hero {
    text-align: left;
  }

  .hero .top {
    align-items: flex-start;
  }

  .logo {
    display: none;
  }

  section {
    padding-top: 1.4rem;
  }

  .sec-title {
    break-after: avoid;
  }

  .role {
    break-after: avoid;
  }

  .closing,
  footer {
    display: none;
  }

  .entry {
    break-inside: avoid;
  }
}

/* contact dialog */
dialog {
  width: min(32rem, calc(100vw - 2rem));
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: var(--r-l);
  background: var(--bg);
  color: var(--ink);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.08);
}

dialog::backdrop {
  background: rgba(10, 14, 10, 0.25);
}

#contact-form {
  padding: 1.4rem 1.5rem 1.5rem;
  display: grid;
  gap: 0.35rem;
}

.cd-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.cd-head h2 {
  margin: 0;
  font-weight: 400;
  font-size: 1.5rem;
}

/* the same typing bubble as the Let's Chat buttons: it plays when the dialog opens,
   bounces a few times, then settles with the dots showing */
.cd-bubble {
  display: inline-block;
  width: 1.15rem;
  height: 1.15rem;
  margin-left: 0.5rem;
  vertical-align: -0.1rem;
  fill: var(--accent);
  overflow: visible;
}

.cd-bubble .dot {
  fill: #000;
  transform-box: fill-box;
  transform-origin: center;
}

dialog[open] .cd-bubble {
  animation: bubble-in 0.45s ease-out 0.15s backwards;
}

dialog[open] .cd-bubble .dot {
  animation:
    dot-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) backwards,
    typing 1.2s ease-in-out 3;
}

dialog[open] .cd-bubble .dot:nth-child(2) {
  animation-delay: 0.55s, 1.15s;
}

dialog[open] .cd-bubble .dot:nth-child(3) {
  animation-delay: 0.69s, 1.33s;
}

dialog[open] .cd-bubble .dot:nth-child(4) {
  animation-delay: 0.83s, 1.51s;
}

@media (prefers-reduced-motion: reduce) {
  dialog[open] .cd-bubble,
  dialog[open] .cd-bubble .dot {
    animation: none;
  }
}

.cd-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--panel); /* same round button as back-to-top */
  color: var(--faint);
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

.cd-close svg {
  width: 0.8rem;
  height: 0.8rem;
  fill: currentColor;
}

.cd-close:hover {
  background: color-mix(in srgb, var(--accent) 14%, var(--panel));
  color: var(--accent);
}

.cd-note {
  margin: 0 0 0.6rem;
  color: var(--muted);
  font-size: 0.95rem;
}

/* the form looks like an email compose window: To / Name / Subject rows, then the body */
.compose {
  margin-top: 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px 4px var(--r) var(--r);
  /* white in light mode, with a soft inner shadow so it looks pressed into the dialog */
  background: #fff;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.07);
  overflow: hidden;
}

/* in dark mode the field goes a shade deeper than the dialog, with a softer edge */
:root[data-theme='dark'] .compose {
  --band: color-mix(in srgb, var(--accent) 42%, #000);
  background: color-mix(in srgb, var(--bg) 55%, #000);
  border-color: color-mix(in srgb, var(--rule) 45%, transparent);
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.5);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .compose {
    --band: color-mix(in srgb, var(--accent) 42%, #000);
    background: color-mix(in srgb, var(--bg) 55%, #000);
    border-color: color-mix(in srgb, var(--rule) 45%, transparent);
    box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.5);
  }
}

/* notepad: a cloth-bound strip across the top, like the spine of a notepad.
   Solid green with a fine woven texture and a slight shade at the edges. */
.compose {
  --band: color-mix(in srgb, var(--accent) 88%, #000);
}

.compose::before {
  content: '';
  display: block;
  height: 1.5rem;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.14), transparent 45%, rgba(0, 0, 0, 0.14)),
    repeating-linear-gradient(to right, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 3px),
    var(--band);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
  position: relative;
  z-index: 1;
}

.cf-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0 0.9rem;
  transition: background 0.15s;
}

/* the dotted divider: small dots with plenty of room between them */
.cf-row::after {
  content: '';
  position: absolute;
  left: 0.9rem;
  right: 0.9rem;
  bottom: 0;
  height: 1px;
  background: repeating-linear-gradient(
    to right,
    color-mix(in srgb, var(--muted) 30%, transparent) 0 1px,
    transparent 1px 6px
  );
}

.cf-k {
  flex: none;
  width: 4rem;
  font-size: 0.9rem;
  color: var(--muted);
}

.cf-to {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0.6rem 0;
  padding: 0.2rem 0.75rem 0.2rem 0.2rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-size: 0.95rem;
  color: var(--ink);
}

.cf-to img {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

#contact-form input,
#contact-form textarea {
  font: inherit;
  font-size: 1.05rem;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: 0;
}

#contact-form input {
  flex: 1;
  min-width: 0;
  padding: 0.95rem 0;
}

#contact-form textarea {
  display: block;
  width: 100%;
  min-height: 9rem;
  padding: 0.9rem 0.9rem 0.8rem;
  resize: vertical;
}

/* visually hidden, still read by screen readers */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* the row you are typing in gets the faintest green tint, no outline */
.cf-row:focus-within {
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

#contact-form input:focus,
#contact-form textarea:focus {
  outline: none;
}

/* the same quiet hairline for buttons and links inside the dialog */
dialog button:focus-visible,
dialog a:focus-visible {
  outline: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  outline-offset: 2px;
}

/* error state: red border plus a short message under the field */
#contact-form {
  --bad: #b3372a;
}

:root[data-theme='dark'] #contact-form {
  --bad: #ec8579;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) #contact-form {
    --bad: #ec8579;
  }
}

/* error rows get a faint red wash instead of a coloured border */
.cf-row:has([aria-invalid='true']) {
  background: color-mix(in srgb, var(--bad) 5%, transparent);
}

/* small light-red pill with an icon */
.cf-err {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: none;
  margin: 0 0 0 auto;
  padding: 0.2rem 0.6rem 0.2rem 0.45rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bad) 11%, transparent);
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--bad);
}

.cf-err svg {
  flex: none;
  width: 0.8rem;
  height: 0.8rem;
  fill: currentColor;
}

.cf-err[hidden] {
  display: none;
}

.cd-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  margin-top: 1rem;
  gap: 1rem;
}

.cd-status {
  margin-top: 0.8rem;
  padding: 0.7rem 0.85rem;
  border-radius: var(--r);
  background: var(--panel);
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.4;
}

.cd-status a {
  color: var(--accent);
}

.cd-status strong {
  font-weight: 400;
  color: var(--ink);
}

.cd-copy {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.cd-status[hidden] {
  display: none;
}

/* Let's chat: the Font Awesome "message-dots" icon after the label.
   At rest it is the outline version. On hover the outline floats up and fades out
   while the solid bubble rises into its place, then the three dots pop in and bounce
   in turn like the typing dots in iMessage.
   The dots in the solid bubble are holes cut out with a mask, so they take the button colour. */
.cta-chat {
  padding: 0 1.5rem;
}

.cta-chat .lbl {
  line-height: 1.4;
}

.cta-chat .bubble {
  display: block;
  flex: none;
  width: 1rem;
  height: 1rem;
  margin-left: 0.45rem;
  position: relative;
  top: 0.12rem;
  fill: currentColor;
  overflow: visible;
}

.cta-chat .out,
.cta-chat .solid {
  transform-box: fill-box;
  transform-origin: center;
  transition:
    opacity 0.3s ease,
    transform 0.3s ease;
}

/* resting: outline shown, solid waiting just below */
.cta-chat .solid {
  opacity: 0;
  transform: translateY(40%);
}

/* black circles inside a mask = holes */
.cta-chat .dot {
  fill: #000;
  transform-box: fill-box;
  transform-origin: center;
}

.cta-chat:hover .out,
.cta-chat:focus-visible .out {
  opacity: 0;
  transform: translateY(-40%);
}

.cta-chat:hover .solid,
.cta-chat:focus-visible .solid {
  opacity: 1;
  transform: none;
}

.cta-chat:hover .dot,
.cta-chat:focus-visible .dot {
  animation:
    dot-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) backwards,
    typing 1.2s ease-in-out infinite;
}

.cta-chat:hover .dot:nth-child(2),
.cta-chat:focus-visible .dot:nth-child(2) {
  animation-delay: 0.3s, 0.9s;
}

.cta-chat:hover .dot:nth-child(3),
.cta-chat:focus-visible .dot:nth-child(3) {
  animation-delay: 0.44s, 1.08s;
}

.cta-chat:hover .dot:nth-child(4),
.cta-chat:focus-visible .dot:nth-child(4) {
  animation-delay: 0.58s, 1.26s;
}

/* touch screens have no hover, so show the finished, animated icon from the start */
@media (hover: none) {
  .cta-chat .out {
    opacity: 0;
  }

  .cta-chat .solid {
    opacity: 1;
    transform: none;
  }

  .cta-chat .dot {
    animation:
      dot-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) backwards,
      typing 1.2s ease-in-out infinite;
  }

  .cta-chat .dot:nth-child(2) {
    animation-delay: 0.3s, 0.9s;
  }

  .cta-chat .dot:nth-child(3) {
    animation-delay: 0.44s, 1.08s;
  }

  .cta-chat .dot:nth-child(4) {
    animation-delay: 0.58s, 1.26s;
  }
}

@keyframes dot-in {
  from {
    transform: scale(0);
  }

  to {
    transform: scale(1);
  }
}

@keyframes typing {
  0%,
  50%,
  100% {
    opacity: 1;
    transform: translateY(0);
  }

  25% {
    opacity: 0.55;
    transform: translateY(-45px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cta-chat .out,
  .cta-chat .solid {
    transition: none;
  }

  .cta-chat:hover .dot,
  .cta-chat:focus-visible .dot,
  .cta-chat .dot {
    animation: none;
  }
}

.dl-menu .fmt {
  display: inline-block;
  font-weight: 400;
  font-size: 0.62rem;
  line-height: 1;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.15rem 0.35rem 0.17rem;
  margin-right: 0.6rem;
  border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 11%, var(--bg));
  color: var(--accent);
  vertical-align: 0.1em;
}

/* Download button inside the contact popup: labelled, menu opens upward */
.dl-trigger.labeled {
  height: 2.7rem;
  padding: 0 0.9rem;
  gap: 0.5rem;
  border: 1px solid var(--rule);
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
}

.dl-trigger.labeled:hover,
.dl-trigger.labeled[aria-expanded='true'] {
  background: var(--panel);
  border-color: var(--faint);
}

.dl-trigger.labeled .i-pdf {
  width: 1.1rem;
  height: 1.1rem;
  color: var(--muted);
}

.dl-menu.up {
  top: auto;
  bottom: calc(100% + 0.4rem);
  left: 0;
  transform: none;
}

.cd-actions {
  justify-content: space-between;
}

dialog {
  overflow: visible;
}

/* darker dimming behind the popup in dark mode */
:root[data-theme='dark'] dialog::backdrop {
  background: rgba(0, 0, 0, 0.68);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) dialog::backdrop {
    background: rgba(0, 0, 0, 0.68);
  }
}

/* tooltip on the icon-only download button */
.dl-trigger[data-tip] {
  position: relative;
}

.dl-trigger[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 0.35rem);
  left: 50%;
  transform: translate(-50%, 3px);
  white-space: nowrap;
  padding: 0.35rem 0.6rem;
  border-radius: 4px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font);
  font-size: 0.85rem;
  line-height: 1.2;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0.15s,
    transform 0.15s;
  z-index: 6;
}

.dl-trigger[data-tip][aria-expanded='false']:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
}

@media (hover: hover) {
  .dl-trigger[data-tip][aria-expanded='false']:hover::after {
    opacity: 1;
    transform: translate(-50%, 0);
    transition-delay: 0.25s;
  }
}

/* "Download" item in the nav menu */
.dl-nav {
  position: relative;
}

.links .dl-trigger.navdl {
  height: auto;
  padding: 0.2rem 0;
  gap: 0.3rem;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--muted);
  font: inherit;
  font-size: 0.95rem;
}

.links .dl-trigger.navdl:hover,
.links .dl-trigger.navdl[aria-expanded='true'] {
  background: none;
  color: var(--ink);
}

.links .dl-trigger.navdl .i-chev {
  width: 0.65rem;
  height: 0.65rem;
}

.dl-nav .dl-menu {
  top: calc(100% + 0.9rem);
  left: -0.5rem;
  transform: none;
}

.links .dl-menu a {
  display: flex;
  padding: 0.5rem 0.7rem;
  font-size: 0.98rem;
  color: var(--ink);
  border-radius: var(--r-s);
}

.links .dl-menu a:hover {
  background: var(--panel);
  color: var(--ink);
}

@media (max-width: 720px) {
  .links .dl-trigger.navdl {
    display: flex;
    width: 100%;
    justify-content: space-between;
    padding: 0.55rem 0.8rem;
    border-radius: var(--r-s);
    font-size: 1rem;
  }

  .links .dl-trigger.navdl:hover {
    background: var(--panel);
  }

  .dl-nav .dl-menu {
    position: static;
    min-width: 0;
    margin: 0.1rem 0 0.3rem;
    box-shadow: none;
    border: 0;
    background: var(--panel);
    border-radius: var(--r);
  }

  .links .dl-menu a {
    padding: 0.55rem 0.7rem;
  }
}

/* nav items share one box so Download lines up with the links */
.links .dl-trigger.navdl {
  height: 2.1rem;
  padding: 0 0.8rem;
  gap: 0.35rem;
  border-radius: 8px;
}

.links .dl-trigger.navdl:hover,
.links .dl-trigger.navdl[aria-expanded='true'] {
  background: var(--panel);
  color: var(--ink);
}

.dl-nav .dl-menu {
  left: 0;
}

@media (max-width: 720px) {
  .links {
    gap: 0;
  }

  .float:not(.scrolled) .links {
    margin-left: 0;
  }

  .links > li > a {
    height: auto;
    padding: 0.55rem 0.8rem;
    border-radius: var(--r-s);
    font-size: 1rem;
    display: block;
  }

  .links .dl-trigger.navdl {
    display: none;
  }

  .dl-nav .dl-menu,
  .dl-nav .dl-menu[hidden] {
    display: block;
    position: static;
    min-width: 0;
    margin: 0.5rem 0 0;
    padding: 0.3rem;
    border: 0;
    border-radius: var(--r);
    background: var(--panel);
    box-shadow: none;
  }

  .dl-nav .dl-head {
    padding: 0.5rem 0.6rem 0.25rem;
  }

  .links .dl-menu a {
    padding: 0.55rem 0.8rem;
    border-radius: var(--r-s);
  }
}

/* first nav item: a waving hand that links to the top of the page */
.links .home svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

.links .home .home-t {
  display: none;
}

@media (max-width: 720px) {
  .links .home {
    display: flex;
    align-items: center;
    gap: 0.6rem;
  }

  .links .home svg {
    width: 1rem;
    height: 1rem;
  }

  .links .home .home-t {
    display: inline;
  }
}

@media (max-width: 720px) {
  .links li:has(> .home) {
    display: none;
  }
}

.float.scrolled .links li:has(> .home) {
  display: none;
}

@media (max-width: 720px) {
  .links .dl-menu a {
    border: 1px solid transparent;
  }

  .links .dl-menu a:hover,
  .links .dl-menu a:focus-visible,
  .links .dl-menu a:active {
    background: var(--bg);
    border-color: var(--rule);
  }
}

/* the footer stays on one line on phones too; it only stacks if the screen is really tiny */
@media (max-width: 340px) {
  .foot {
    flex-direction: column;
    justify-content: center;
    text-align: center;
  }
}

#contact-form {
  grid-template-columns: minmax(0, 1fr);
}

/* contact form actions: Download and Copy email are quiet, Send leads */
.cd-aux {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: nowrap;
  flex: 0 0 auto;
  margin-left: -0.7rem;
}

.cd-actions .dl-trigger.labeled,
.cd-actions .copy-btn {
  padding: 0 0.7rem;
  white-space: nowrap;
  flex: 0 0 auto;
  border-color: transparent;
  color: var(--muted);
}

.cd-actions .dl-trigger.labeled:hover,
.cd-actions .dl-trigger.labeled[aria-expanded='true'],
.cd-actions .copy-btn:hover {
  background: var(--panel);
  border-color: transparent;
  color: var(--ink);
}

.cd-actions .dl-trigger.labeled .i-pdf,
.cd-actions .copy-btn .i-copy {
  width: 0.9rem;
  height: 0.9rem;
  color: inherit;
  opacity: 0.55;
}

.cd-actions .dl-trigger.labeled:hover .i-pdf,
.cd-actions .dl-trigger.labeled[aria-expanded='true'] .i-pdf,
.cd-actions .copy-btn:hover .i-copy {
  color: var(--accent);
  opacity: 1;
}

.copy-btn.copied {
  color: var(--accent);
}

.cd-actions .btn.solid {
  white-space: nowrap;
}

@media (max-width: 560px) {
  .cd-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0.6rem;
  }

  .cd-aux {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    width: 100%;
    margin-left: 0;
    gap: 0.6rem;
  }

  .cd-aux .dl {
    min-width: 0;
  }

  .cd-aux .dl {
    display: flex;
  }

  .cd-aux .dl-trigger.labeled,
  .cd-aux .copy-btn {
    width: 100%;
    min-width: 0;
    padding: 0 0.5rem;
    justify-content: center;
    background: var(--panel);
  }

  .cd-actions .btn.solid {
    width: 100%;
  }
}

/* tooltips would be clipped inside the dialog */
.cd-actions .dl-trigger[data-tip]::after {
  display: none;
}

/* navbar Download: tooltip opens below the pill */
.links .dl-trigger.navdl[data-tip]::after {
  bottom: auto;
  top: calc(100% + 0.9rem);
  transform: translate(-50%, -3px);
}

.links .dl-trigger.navdl[data-tip][aria-expanded='false']:focus-visible::after {
  transform: translate(-50%, 0);
}

@media (hover: hover) {
  .links .dl-trigger.navdl[data-tip][aria-expanded='false']:hover::after {
    transform: translate(-50%, 0);
  }
}

/* reserve room so the expanded switch doesn't cover the nav links */
@media (min-width: 721px) {
  .themesw {
    margin-left: 4.2rem;
  }
}

/* ---------------------------------------------------------------
   Night sky (dark mode only)
   Sits behind the hero.

   Layers, back to front:
     .na .nb   soft nebula clouds that drift slowly
     .dust     tiny stars, never move, so the sky always feels full
     .s1-.s3   the bigger four-point stars, these are the ones that twinkle
     .shoot    the occasional meteor
   --------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
}

.sky {
  --o: 0.7;
  --shoot: rgba(190, 235, 184, 0.85);

  --na: url(assets/images/sky/neb-a.png);
  --nb: url(assets/images/sky/neb-b.png);
  --dust: url(assets/images/sky/neb-dust.png);
  --a1: url(assets/images/sky/neb-stars-1.png);
  --a2: url(assets/images/sky/neb-stars-2.png);
  --a3: url(assets/images/sky/neb-stars-3.png);

  display: none;
  position: absolute;
  inset: 0 0 -4rem;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(#000 40%, transparent);
  mask-image: linear-gradient(#000 40%, transparent);
}

/* only show it in dark mode */
:root[data-theme='dark'] .sky {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .sky {
    display: block;
  }
}

/* every layer is a full-size image, a bit wider than the box so drifting never shows an edge */
.sky i {
  position: absolute;
  inset: 0 -12%;
  display: block;
  background: center top / cover no-repeat;
  image-rendering: pixelated;
}

.sky .na {
  background-image: var(--na);
  opacity: var(--neb, 1);
  animation:
    sky-drift-a 34s ease-in-out infinite alternate,
    sky-breathe 9s ease-in-out infinite;
}

.sky .nb {
  background-image: var(--nb);
  opacity: var(--neb, 1);
  animation:
    sky-drift-b 46s ease-in-out infinite alternate,
    sky-breathe 11s ease-in-out -4s infinite;
}

.sky .dust {
  background-image: var(--dust);
  opacity: var(--o);
}

/* three groups of big stars on different timers, so they never blink together */
.sky .s1 {
  background-image: var(--a1);
  animation: sky-twinkle 3.4s ease-in-out infinite;
}
.sky .s2 {
  background-image: var(--a2);
  animation: sky-twinkle 4.4s ease-in-out -1.6s infinite;
}
.sky .s3 {
  background-image: var(--a3);
  animation: sky-twinkle 5.6s ease-in-out -3s infinite;
}

/* meteors */
.sky .shoot {
  position: absolute;
  width: 110px;
  height: 2px;
  border-radius: 1px;
  opacity: 0;
  background: linear-gradient(90deg, transparent, var(--shoot));
  box-shadow: 0 0 6px 1px rgba(190, 235, 184, 0.35);
  animation: sky-meteor 16s linear infinite;
}

.sky .f1 {
  left: 12%;
  top: 6%;
}
.sky .f2 {
  left: 58%;
  top: 4%;
  animation-delay: -8s;
}

/* ---------------------------------------------------------------
   Closing card
   The card keeps its own background colour and gets the sky on top.
   Dark mode: the full night sky (clouds, stars, meteors).
   Light mode: just deep-green stars and the odd meteor, because the
   pale clouds looked splotchy on the light card.
   --------------------------------------------------------------- */

.closing-card .sky {
  /* light mode: deep green stars so they show on the pale card */
  --c1: url(assets/images/sky/light-stars-1.png);
  --c2: url(assets/images/sky/light-stars-2.png);
  --c3: url(assets/images/sky/light-stars-3.png);
  --shoot: rgba(20, 100, 45, 0.8);
  --show-clouds: none;
  --show-dust: none;

  display: block; /* shown in light mode too */
  inset: 0;
  --o: 0.6;
  -webkit-mask-image: none;
  mask-image: none;
}

.closing-card .sky .na,
.closing-card .sky .nb {
  display: var(--show-clouds);
}

.closing-card .sky .dust {
  display: var(--show-dust);
}

.closing-card .sky .st {
  --o: 0.9;
}

.closing-card .sky .s1 { background-image: var(--c1); }
.closing-card .sky .s2 { background-image: var(--c2); }
.closing-card .sky .s3 { background-image: var(--c3); }

.closing-card .sky .shoot {
  box-shadow: none;
}

/* dark mode: back to the pale stars, the clouds and the star dust */
:root[data-theme='dark'] .closing-card .sky {
  --c1: var(--a1);
  --c2: var(--a2);
  --c3: var(--a3);
  --shoot: rgba(190, 235, 184, 0.85);
  --show-clouds: block;
  --show-dust: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .closing-card .sky {
    --c1: var(--a1);
    --c2: var(--a2);
    --c3: var(--a3);
    --shoot: rgba(190, 235, 184, 0.85);
    --show-clouds: block;
    --show-dust: block;
  }
}

@keyframes sky-drift-a {
  from {
    transform: translateX(-5%) translateY(-1%) scale(1.02);
  }
  to {
    transform: translateX(5%) translateY(2%) scale(1.05);
  }
}

@keyframes sky-drift-b {
  from {
    transform: translateX(5%) translateY(2%) scale(1.05);
  }
  to {
    transform: translateX(-5%) translateY(-1%) scale(1.02);
  }
}

@keyframes sky-breathe {
  0%,
  100% {
    filter: brightness(0.8);
  }
  50% {
    filter: brightness(1.2);
  }
}

@keyframes sky-twinkle {
  0%,
  100% {
    opacity: var(--o);
  }
  35% {
    opacity: calc(var(--o) * 0.15);
  }
  60% {
    opacity: calc(var(--o) * 0.75);
  }
  80% {
    opacity: calc(var(--o) * 0.3);
  }
}

/* a quick streak from top-left to bottom-right, then a long pause */
@keyframes sky-meteor {
  0% {
    opacity: 0;
    transform: translate(0, 0) rotate(24deg);
  }
  1% {
    opacity: 1;
  }
  9% {
    opacity: 0;
    transform: translate(360px, 160px) rotate(24deg);
  }
  100% {
    opacity: 0;
    transform: translate(360px, 160px) rotate(24deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sky i {
    animation: none !important;
  }
}

/* the copyright icon in the footer: click or tap it to show the build time (YYMMDD HHMM).
   The stamp is set by hand when the page is written. */
.copy-mark {
  display: inline-flex;
  vertical-align: -0.04em;
  margin-right: 0.15em;
  width: 0.8em;
  height: 0.8em;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.copy-mark svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.stamp {
  color: color-mix(in srgb, var(--faint) 42%, var(--bg));
  animation: fade-in 0.25s ease-out;
}

.stamp[hidden] {
  display: none;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}
