/*
 * Gabriel Palmisano, personal site.
 *
 * The visual language is the Berlin deck's: MapLibre's blue on a white a
 * breath towards blue, Alata for titles, Inter Tight for text, JetBrains Mono
 * for numbers, dates and coordinates. Hairlines, position and type size carry
 * the structure; filled boxes only where something is being pointed at.
 */

/* Fonts: served from the site, latin and latin-ext subsets only. */
@font-face {
  font-family: 'Alata';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/alata-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Alata';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/alata-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter Tight';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/intertight-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter Tight';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/intertight-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(fonts/jetbrainsmono-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(fonts/jetbrainsmono-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* The ground: a white a breath towards the palette blue. */
  --ground: #F7F9FC;
  --surface: #EBF1FA;
  --primary: #285DAA;
  --primary-deep: #1F4C8F;
  --accent: #95BEFA;
  --ink: #111725;

  /* The text ramp is the ink at three strengths. */
  --text: #111725;
  --text-2: rgba(17, 23, 37, 0.78);
  --muted: rgba(17, 23, 37, 0.58);

  --hairline: rgba(17, 23, 37, 0.12);
  --hairline-strong: rgba(17, 23, 37, 0.24);

  /* The light accent behind a word, like a highlighter. Never text colour. */
  --marker: rgba(149, 190, 250, 0.55);

  --display: 'Alata', 'Inter Tight', system-ui, sans-serif;
  --sans: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --topbar: 64px;
  --gutter: clamp(32px, 6vw, 112px);
  --measure: 36rem;
}

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

html {
  background: var(--ground);
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--text-2);
  font-family: var(--sans);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

a:hover {
  color: var(--primary-deep);
}

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 400;
  color: var(--ink);
  margin: 0;
}

h1 {
  font-size: clamp(48px, 5.4vw, 92px);
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0.35em 0 0.3em;
}

h2 {
  font-size: clamp(34px, 3.3vw, 54px);
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0.25em 0 0.7em;
}

h3 {
  font-size: 22px;
  line-height: 1.25;
  margin: 2.4em 0 0.7em;
}

p {
  margin: 0 0 1em;
  max-width: var(--measure);
}

/* One word under the highlighter, as in the Berlin deck: a straight flat
   band behind the letters, from the baseline to the top of the lowercase,
   never below the baseline. No slant and no animation: the rest of the page
   is geometric, and the band is emphasis, not an effect. */
.mark {
  position: relative;
  z-index: 0;
  white-space: nowrap;
}

.mark::before {
  content: '';
  position: absolute;
  z-index: -1;
  left: -0.08em;
  right: -0.08em;
  /* Measured in the browser on Alata, the titles' face: the baseline sits
     0.27em above the bottom of the box and the lowercase is 0.46em tall. */
  bottom: var(--mark-bottom, 0.25em);
  height: var(--mark-height, 0.49em);
  border-radius: 0.08em;
  background: var(--marker);
}

/* Inter Tight, in the hero line: baseline at 0.24em, lowercase 0.55em. */
.lead .mark {
  --mark-bottom: 0.21em;
  --mark-height: 0.58em;
}

.kicker {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary);
  margin: 0;
}

.lead {
  font-size: 21px;
  line-height: 1.5;
  color: var(--ink);
}

/* Buttons: a pill for the one action, a hairline for the others. */
.button {
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 20px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  color: var(--ink);
  font-weight: 500;
  font-size: 16px;
  text-decoration: none;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}

.button:hover {
  border-color: var(--ink);
  color: var(--ink);
}

.button.primary {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.button.primary:hover {
  background: var(--primary-deep);
  border-color: var(--primary-deep);
  color: #fff;
}

/* Rows of label and value, divided by hairlines. */
.rows {
  margin: 0;
  max-width: var(--measure);
}

.rows .row {
  display: grid;
  grid-template-columns: 8rem 1fr;
  column-gap: 16px;
  padding: 0.7em 0;
  border-top: 1px solid var(--hairline);
}

.rows .row:last-child {
  border-bottom: 1px solid var(--hairline);
}

.rows dt {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.3em;
}

.rows dd {
  margin: 0;
  color: var(--ink);
  font-size: 16px;
}

/* ------------------------------------------------------------------ */
/* Page frame: text on the left, the map fixed on the right.          */
/* ------------------------------------------------------------------ */

.content {
  position: relative;
  z-index: 2;
  width: 50vw;
  padding: 0 var(--gutter);
}

.section {
  padding: 22vh 0 6vh;
  scroll-margin-top: var(--topbar);
}

.section.hero {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(var(--topbar) + 4vh) 0 8vh;
}

.topbar {
  position: fixed;
  z-index: 10;
  top: 0;
  left: 0;
  width: 50vw;
  height: var(--topbar);
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  gap: 28px;
  background: linear-gradient(180deg, var(--ground) 62%, rgba(247, 249, 252, 0));
}

.topbar .brand {
  font-family: var(--display);
  font-size: 18px;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.topbar .sections {
  display: flex;
  gap: 20px;
  margin-left: auto;
}

.topbar .sections a {
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}

.topbar .sections a:hover {
  color: var(--ink);
}

.topbar .sections a.current {
  color: var(--ink);
  border-bottom-color: var(--primary);
}

.topbar .lang {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  padding: 6px 10px;
  margin-right: -10px;
  border-radius: 999px;
  transition: background-color 160ms ease;
}

.topbar .lang:hover {
  background: var(--surface);
}

.topbar .lang .on {
  color: var(--ink);
  font-weight: 600;
}

.topbar .lang .sep {
  margin: 0 4px;
  opacity: 0.5;
}

/* The map pane. Scenery only: every pointer event goes through it to the
   page, so the wheel scrolls the page wherever the cursor is. */
.map-pane {
  position: fixed;
  z-index: 1;
  top: 0;
  right: 0;
  width: 50vw;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.map-pane,
.map-pane * {
  pointer-events: none !important;
}

/* Where there is a mouse, the map's own canvas takes the pointer back, so a
   dot can say what it is. The wheel still scrolls the page: the map has no
   wheel zoom, and the event goes on to the document. Phones keep the band
   inert, because a finger on it has to scroll the text. */
@media (hover: hover) and (pointer: fine) and (min-width: 901px) {
  .map-pane canvas.maplibregl-canvas {
    pointer-events: auto !important;
  }
}

.map-view {
  position: absolute;
  inset: 0;
}

/* "Drag to spin the globe", said by a cursor with a name tag, like the
   cursors that show where Claude is pointing. Anchored on the open source
   globe with the map's own numbers: the globe's centre sits at 57% of the
   pane (the fade takes 14% on the left) and halfway down, and it is 0.8 of
   the smaller of the space left and the height across. The cursor rests on
   its lower right, glides in, presses, drags a little, lets go, and loops.
   Only where there is a mouse to drag with. */
.map-cursor {
  display: none;
}

@media (hover: hover) and (pointer: fine) and (min-width: 901px) {
  .map-cursor {
    --globe: calc(0.8 * min(43vw, 100vh));
    position: absolute;
    z-index: 3;
    left: calc(57% + var(--globe) * 0.2);
    top: calc(50% + var(--globe) * 0.16);
    display: block;
  }

  .cursor-arrow {
    display: block;
    fill: var(--primary);
    stroke: #fff;
    stroke-width: 1.4px;
    stroke-linejoin: round;
    filter: drop-shadow(0 2px 4px rgba(17, 23, 37, 0.25));
    transform-origin: 1px 1px;
  }

  .cursor-label {
    position: absolute;
    left: 16px;
    top: 20px;
    padding: 5px 10px;
    border-radius: 4px 999px 999px 999px;
    background: var(--primary);
    color: #fff;
    font-family: var(--sans);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(40, 93, 170, 0.3);
  }

  @media (prefers-reduced-motion: no-preference) {
    .map-cursor {
      animation: cursor-move 5.2s cubic-bezier(0.45, 0, 0.25, 1) 0.6s infinite both;
    }

    .cursor-arrow {
      animation: cursor-press 5.2s ease 0.6s infinite both;
    }
  }
}

/* Glide in from the lower right, rest, drag a little to the left as if
   spinning the globe, rest again, fade out. */
@keyframes cursor-move {
  0% {
    opacity: 0;
    transform: translate(46px, 34px);
  }
  14% {
    opacity: 1;
    transform: translate(0, 0);
  }
  34% {
    transform: translate(0, 0);
  }
  58% {
    transform: translate(-56px, -6px);
  }
  84% {
    opacity: 1;
    transform: translate(-56px, -6px);
  }
  100% {
    opacity: 0;
    transform: translate(-56px, -6px);
  }
}

/* The press, while dragging: the arrow tips a little, like a finger down. */
@keyframes cursor-press {
  0%,
  30%,
  62%,
  100% {
    transform: scale(1);
  }
  35%,
  57% {
    transform: scale(0.86);
  }
}

/* What a dot is, next to the pointer. */
.map-tip {
  position: absolute;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px 9px;
  border-radius: 10px;
  background: rgba(247, 249, 252, 0.94);
  box-shadow: 0 0 0 1px var(--hairline), 0 8px 24px rgba(17, 23, 37, 0.12);
  transform: translate(18px, -50%);
  white-space: nowrap;
}

.map-tip.flip {
  transform: translate(calc(-100% - 18px), -50%);
}

.map-tip .tip-title {
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.2;
  color: var(--ink);
}

.map-tip .tip-entry {
  display: flex;
  flex-direction: column;
  padding-top: 6px;
}

.map-tip .tip-main {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
}

.map-tip .tip-sub {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.45;
  color: var(--muted);
}

.map-view > div:last-child {
  width: 100%;
  height: 100%;
}

/* The left edge of the map fades into the page instead of ending on a line. */
.map-fade {
  position: absolute;
  inset: 0 auto 0 0;
  width: 14%;
  background: linear-gradient(90deg, var(--ground), rgba(247, 249, 252, 0));
}

.map-caption {
  position: absolute;
  right: 24px;
  bottom: 20px;
  margin: 0;
  max-width: calc(100% - 48px);
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(247, 249, 252, 0.88);
  box-shadow: 0 0 0 1px var(--hairline);
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* With a selected talk stop the caption carries a cross to let it go: the
   one thing in the map pane that takes a click on every device. */
.map-caption.with-clear {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-right: 4px;
}

.map-pane .map-caption .caption-clear {
  pointer-events: auto !important;
}

.caption-clear {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  font: 500 17px/1 var(--sans);
  cursor: pointer;
  transition: background-color 160ms ease;
}

.caption-clear:hover {
  background: var(--accent);
}

/* Until Flutter draws, the globe's outline sits where the live one will. */
.map-loader {
  position: absolute;
  inset: 0;
}

.map-loader-globe {
  position: absolute;
  width: 112vh;
  height: 112vh;
  left: 8vw;
  top: calc(50% - 56vh);
  border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #DCE7F7, #CFDDF3 62%);
  box-shadow: 0 18px 36px rgba(17, 23, 37, 0.12);
  animation: breathe 2.4s ease-in-out infinite;
}

@keyframes breathe {
  50% {
    opacity: 0.7;
  }
}

/* ------------------------------------------------------------------ */
/* Hero                                                               */
/* ------------------------------------------------------------------ */

.hero .role {
  font-size: 17px;
  font-weight: 500;
  color: var(--text-2);
  margin-bottom: 1.6em;
}

.now {
  margin: 1.4em 0 2.2em;
  max-width: var(--measure);
}

.now > div {
  display: grid;
  grid-template-columns: 8rem 1fr;
  column-gap: 16px;
  padding: 0.65em 0;
  border-top: 1px solid var(--hairline);
}

.now > div:last-child {
  border-bottom: 1px solid var(--hairline);
}

.now dt {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.35em;
}

.now dd {
  margin: 0;
  color: var(--ink);
  font-size: 16px;
}

.now .date {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  margin-left: 10px;
  white-space: nowrap;
}

.actions,
.links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* Brand marks in the site's ink, never in the brands' own colours. */
.icon {
  display: block;
  flex: none;
}

/* GitHub, LinkedIn and Sessionize next to the hero buttons, after a hairline. */
.quick {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding-left: 14px;
  border-left: 1px solid var(--hairline-strong);
}

.icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--text-2);
  transition: color 160ms ease, background-color 160ms ease;
}

.icon-link:hover {
  color: var(--primary);
  background: var(--surface);
}

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

.channels dt .icon {
  color: var(--text-2);
}

/* ------------------------------------------------------------------ */
/* About                                                              */
/* ------------------------------------------------------------------ */

.about-head {
  display: flex;
  align-items: center;
  gap: 20px;
  margin: 0.25em 0 0.7em;
}

.about-head h2 {
  margin: 0;
}

/* The whole photo, not cropped into a circle: a stage shot, square, with
   rounded corners. */
.portrait {
  flex: none;
  width: 120px;
  height: 120px;
  border-radius: 14px;
  box-shadow: 0 0 0 1px var(--hairline);
}

/* The route rail, as on the about slide in Berlin. */
.rail {
  list-style: none;
  margin: 2.2em 0 0;
  padding: 0 0 0 30px;
  position: relative;
}

.rail::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 0.9em;
  bottom: 0.9em;
  width: 2px;
  background: linear-gradient(var(--primary) 50%, transparent 0) 0 0 / 2px 8px repeat-y;
}

.rail .stop {
  position: relative;
}

.rail .stop::before {
  content: '';
  position: absolute;
  left: -30px;
  top: 0.55em;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ground);
  box-shadow: inset 0 0 0 2.5px var(--primary);
}

.rail .stop:last-child::before {
  background: var(--primary);
  box-shadow: 0 0 0 5px rgba(40, 93, 170, 0.16);
}

.rail .name {
  display: block;
  font-family: var(--display);
  font-size: 26px;
  line-height: 1.2;
  color: var(--ink);
  transition: color 160ms ease;
}

/* The stop whose dot the reader points at on the map. */
.rail .stop.pointed .name {
  color: var(--primary);
}

.rail .what {
  font-size: 15px;
  color: var(--muted);
}

/* Every day: the three tools that fill the day, above the rows. */
.daily {
  max-width: var(--measure);
  margin: 0 0 1.4em;
}

.daily-label {
  display: block;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 0.3em;
}

.daily-items {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(20px, 1.7vw, 26px);
  line-height: 1.3;
  color: var(--ink);
}

/* A tool's name never breaks across lines; the list wraps between tools. */
.daily-items span {
  white-space: nowrap;
}

.daily-items .sep {
  color: var(--accent);
  margin: 0 0.35em;
}

/* The way between two stops: smaller and lighter than a stop's own line,
   with an arrow down the rail, so it reads as "from here to there". */
.rail .leg {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: rgba(17, 23, 37, 0.45);
  padding: 0.9em 0;
}

.rail .leg .arrow {
  color: var(--primary);
  font-size: 12px;
}

/* ------------------------------------------------------------------ */
/* Open source                                                        */
/* ------------------------------------------------------------------ */

.figures {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  max-width: var(--measure);
  margin: 2.2em 0 0.6em;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.figure {
  padding: 1.1em 1.2em 1.1em 0;
}

.figure + .figure {
  padding-left: 1.2em;
  border-left: 1px solid var(--hairline);
}

.figure .value {
  display: block;
  font-family: var(--mono);
  font-size: clamp(30px, 2.6vw, 42px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--primary);
}

.figure .label {
  display: block;
  margin-top: 0.4em;
  font-size: 14px;
  line-height: 1.35;
  color: var(--muted);
}

/* Where the two live figures come from, small, right under them. */
.source {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 2.2em;
}

.facts {
  list-style: none;
  padding: 0;
  margin: 0 0 2em;
  max-width: var(--measure);
}

.facts li {
  padding: 0.7em 0;
  border-top: 1px solid var(--hairline);
  color: var(--ink);
  font-size: 16px;
}

.facts li:last-child {
  border-bottom: 1px solid var(--hairline);
}

.facts .lead-in {
  font-weight: 600;
}

/* The numbers behind a fact, on their own line, a step quieter. */
.facts .detail {
  display: block;
  margin-top: 0.3em;
  color: var(--text-2);
}

/* ------------------------------------------------------------------ */
/* Talks                                                              */
/* ------------------------------------------------------------------ */

.stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin-bottom: 0.6em;
}

.stat {
  font-size: 15px;
  color: var(--muted);
  white-space: nowrap;
}

.stat .value {
  font-family: var(--mono);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.hint {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 1.4em;
}

.talk-list {
  max-width: var(--measure);
}

.talk {
  padding: 1.6em 0 1.2em;
  border-top: 1px solid var(--hairline);
}

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

.talk-head h3 {
  margin: 0;
  font-size: 21px;
}

.tag {
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-2);
  padding: 2px 7px;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
}

.summary {
  font-size: 16px;
  margin: 0.5em 0 0.9em;
}

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

.stops .stop {
  display: grid;
  grid-template-columns: 7.4rem 1fr auto;
  column-gap: 14px;
  align-items: baseline;
  padding: 0.45em 0.6em;
  margin: 0 -0.6em;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 160ms ease;
}

.stops .stop:hover,
.stops .stop.focused {
  background: var(--surface);
}

.stops .date {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}

.stops .upcoming .date {
  color: var(--primary);
}

.stops .event {
  font-size: 16px;
  color: var(--ink);
}

.stops .city {
  font-size: 14px;
  color: var(--muted);
  text-align: right;
}

.stops .extra {
  grid-column: 2 / 4;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 14px;
}

.badge {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary);
  padding-top: 2px;
}

.invite {
  margin-top: 1.8em;
  font-size: 16px;
}

/* ------------------------------------------------------------------ */
/* Work                                                               */
/* ------------------------------------------------------------------ */

.jobs {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--measure);
}

.job {
  padding: 1.5em 0 1.1em;
  border-top: 1px solid var(--hairline);
}

.job-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
}

.job-head h3 {
  margin: 0;
  font-size: 22px;
}

.job-head .role {
  font-size: 16px;
  font-weight: 500;
  color: var(--text-2);
}

.job .meta {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  margin: 0.3em 0 0.6em;
}

.job ul {
  margin: 0;
  padding-left: 1.1em;
  font-size: 16px;
}

.job li {
  margin: 0.35em 0;
}

.job li::marker {
  color: var(--primary);
}

.studies {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--measure);
}

.studies li {
  padding: 0.65em 0;
  border-top: 1px solid var(--hairline);
  font-size: 16px;
  color: var(--ink);
}

.studies li:last-child {
  border-bottom: 1px solid var(--hairline);
}

/* ------------------------------------------------------------------ */
/* Contact                                                            */
/* ------------------------------------------------------------------ */

.section.contact {
  min-height: 100vh;
  min-height: 100svh;
  padding-bottom: 0;
  /* The email sizes itself to this column. */
  container-type: inline-size;
}

.email {
  display: inline-block;
  font-family: var(--display);
  font-size: clamp(26px, 2.5vw, 40px);
  /* On one line wherever it fits: the address is about 14.7 times as wide
     as its font size in Alata, so a phone or a narrow window shrinks it
     to the column instead of breaking it. */
  font-size: min(clamp(26px, 2.5vw, 40px), 100cqi / 15);
  line-height: 1.2;
  color: var(--primary);
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
  margin: 0.4em 0 1.4em;
  overflow-wrap: anywhere;
  transition: border-color 160ms ease;
}

.email:hover {
  border-bottom-color: var(--primary);
}

.channels dd a {
  color: var(--ink);
  text-decoration: none;
}

.channels dd a:hover {
  color: var(--primary);
  text-decoration: underline;
}

.colophon {
  margin-top: 5em;
  padding: 1.4em 0 3em;
  border-top: 1px solid var(--hairline);
  font-size: 13px;
  color: var(--muted);
}

.colophon p {
  margin: 0.25em 0;
}

/* ------------------------------------------------------------------ */
/* Narrower desktops: the nav would crowd the name, so it goes.       */
/* ------------------------------------------------------------------ */

@media (max-width: 1180px) {
  .topbar .sections {
    display: none;
  }

  .topbar .lang {
    margin-left: auto;
  }
}

/* ------------------------------------------------------------------ */
/* Phones and narrow windows: the map becomes a band across the top.  */
/* ------------------------------------------------------------------ */

@media (max-width: 900px) {
  :root {
    --band: clamp(220px, 36vh, 340px);
    --gutter: 20px;
  }

  body {
    font-size: 17px;
  }

  .map-pane {
    width: 100vw;
    height: var(--band);
    background: var(--ground);
    box-shadow: 0 1px 0 var(--hairline);
    z-index: 5;
  }

  .map-fade {
    display: none;
  }

  /* Wraps instead of cutting: on a phone the hero line is two lines long. */
  .map-caption {
    right: 12px;
    bottom: 10px;
    max-width: calc(100% - 24px);
    font-size: 11px;
    padding: 4px 10px;
    border-radius: 10px;
    white-space: normal;
  }

  /* A finger-sized cross on the phone. */
  .caption-clear {
    width: 32px;
    height: 32px;
  }

  .map-loader-globe {
    width: calc(var(--band) * 1.12);
    height: calc(var(--band) * 1.12);
    left: 30vw;
    top: calc(var(--band) * -0.06);
  }

  /* The bar floats over the band: name on the left, language on the right. */
  .topbar {
    width: 100vw;
    height: 52px;
    padding: 0 12px;
    background: none;
  }

  .topbar .brand,
  .topbar .lang {
    background: rgba(247, 249, 252, 0.9);
    box-shadow: 0 0 0 1px var(--hairline);
    border-radius: 999px;
    padding: 6px 12px;
    font-size: 14px;
  }

  .topbar .lang {
    margin-right: 0;
    font-size: 12px;
  }

  .content {
    width: auto;
    padding: var(--band) var(--gutter) 0;
  }

  .section {
    padding: 14vh 0 4vh;
    scroll-margin-top: var(--band);
  }

  .section.hero {
    min-height: calc(100svh - var(--band));
    justify-content: flex-start;
    padding: 28px 0 6vh;
  }

  h1 {
    font-size: clamp(40px, 11vw, 60px);
    margin-top: 0.3em;
  }

  .lead {
    font-size: 19px;
  }

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

  .figure,
  .figure + .figure {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 0.8em 0;
    border-left: none;
  }

  .figure + .figure {
    border-top: 1px solid var(--hairline);
  }

  .figure .value {
    font-size: 30px;
    min-width: 5.2rem;
  }

  .figure .label {
    margin: 0;
  }

  /* The icons wrap under the buttons: a row of their own, aligned with the
     text, with no separator, and as round buttons a finger can hit. */
  .quick {
    flex-basis: 100%;
    gap: 10px;
    margin: 4px 0 0;
    padding: 0;
    border-left: none;
  }

  .icon-link {
    width: 44px;
    height: 44px;
    box-shadow: inset 0 0 0 1px var(--hairline-strong);
  }

  .stops .stop {
    grid-template-columns: 6.6rem 1fr;
  }

  .stops .city {
    grid-column: 2;
    text-align: left;
  }

  .stops .extra {
    grid-column: 2;
  }

  .rows .row,
  .now > div {
    grid-template-columns: 6.2rem 1fr;
  }

  .section.contact {
    min-height: calc(100svh - var(--band));
  }
}
