/* ==========================================================================
   Tokens
   ========================================================================== */

:root {
  /* Palette: light, with a teal accent. Code sits on the page ground too,
     set like a printed listing rather than a dark terminal */
  --bg: #FFFFFF;          /* page ground */
  --bg-2: #F4F6F5;        /* alternate section ground */
  --surface: #FFFFFF;     /* the editor sheet, form fields */
  --surface-2: #EEF1F0;   /* chips, the browser bar */
  --text: #14181B;        /* body text */
  --muted: #5F6B66;       /* secondary text */
  --line: color-mix(in srgb, var(--text) 12%, transparent);
  --rule: color-mix(in srgb, var(--text) 80%, transparent); /* the heavy rule above a block */
  --accent: #0B7C61;        /* buttons, links, live dot; white text on it */
  --accent-deep: #085E49;  /* hover, keywords in code */
  --accent-soft: #DDF3EA; /* tints */
  --on-accent: #FFFFFF;
  --amber: #D99A1E;       /* away status dot */

  /* Code coloring, on a light ground */
  --code-kw: var(--accent-deep);
  --code-str: #8A5A1B;
  --code-num: #1F5E9E;
  --code-cmt: var(--muted);

  /* Derived tints */
  --wf-fill: color-mix(in srgb, var(--text) 8%, var(--bg));
  --wf-line: color-mix(in srgb, var(--text) 25%, var(--bg));

  /* Type: a serif for headings, a plain sans for everything else */
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-body: "Public Sans", "Helvetica Neue", Arial, sans-serif;
  --display-weight: 500;

  /* Corners: barely rounded, so nothing reads as a pill or a card */
  --radius-s: 3px;
  --radius-m: 3px;
  --radius-l: 3px;
  --radius-pill: 999px;

  /* Fluid type scale: ratio 1.25 at 360px up to 1.5 at 1440px */
  --step--1: clamp(0.875rem, 0.854rem + 0.093vw, 0.9375rem);
  --step-0: clamp(1rem, 0.958rem + 0.185vw, 1.125rem);
  --step-1: clamp(1.25rem, 1.104rem + 0.648vw, 1.6875rem);
  --step-2: clamp(1.5625rem, 1.24rem + 1.435vw, 2.53rem);
  --step-3: clamp(1.9375rem, 1.3125rem + 2.78vw, 3.8rem);
  --step-4: clamp(2.4375rem, 1.354rem + 4.81vw, 5.69rem);
  --step-5: clamp(3.25rem, 1.479rem + 7.87vw, 8.5625rem);

  /* Layout */
  --max: 84rem;
  --gutter: clamp(1rem, 4vw, 3rem);
  --section-space: clamp(5rem, 12vw, 10rem);

  /* Motion */
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  --ease-back: cubic-bezier(0.3, 1.6, 0.5, 1);
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: var(--display-weight);
  line-height: 1.05;
  letter-spacing: -0.005em;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: var(--accent);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 0.16em;
}

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

.wrap {
  width: min(100% - 2 * var(--gutter), var(--max));
  margin-inline: auto;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: -10rem;
  left: var(--gutter);
  z-index: 20;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: var(--on-accent);
}

.skip-link:focus {
  top: 1rem;
}

.button {
  display: inline-flex;
  align-items: center;
  min-height: 3rem;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius-s);
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.25s ease, filter 0.15s ease;
}

.button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px -8px color-mix(in srgb, var(--accent) 70%, transparent);
}

.button:active {
  transform: translateY(0);
  box-shadow: 0 0 0 0 var(--accent);
}

/* Live frames: a site rendered at its real width, scaled to fit its box.
   main.js sets --scale from the box width and data-width. */
.live {
  position: relative;
  overflow: hidden;
}

.live__frame {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(var(--w, 1280) * 1px);
  height: calc(100% / var(--scale, 1));
  border: 0;
  background: var(--surface);
  transform: scale(var(--scale, 1));
  transform-origin: 0 0;
}

/* Sites that can't be embedded (sign-in only) play a screen recording */
.live__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.live__video {
  object-fit: cover;
  background: #000;
}

.viewer__stage.is-recording .browse {
  display: none;
}

/* Image slots: styled fallback until the real file is added */
.shot {
  position: relative;
}

.shot__missing {
  display: none;
}

.shot.is-missing img {
  display: none;
}

.shot.is-missing .shot__missing {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1rem;
  text-align: center;
}

/* ==========================================================================
   Header and footer
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: box-shadow 0.3s ease;
}

.site-header.is-stuck {
  box-shadow: 0 1px 0 var(--line);
}

.site-header__inner {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.35rem 1.5rem;
  padding-block: 0.8rem;
}

.site-header__name {
  grid-area: 1 / 1;
}

.site-header__inner nav {
  grid-column: 1 / -1;
}

.site-nav__book {
  grid-area: 1 / 2;
  justify-self: end;
  display: inline-block;
  padding: 0.4rem 1rem;
  border-radius: var(--radius-s);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.15s ease, filter 0.15s ease;
}

@media (min-width: 48rem) {
  .site-header__inner {
    grid-template-columns: 1fr auto auto;
  }

  .site-header__inner nav {
    grid-area: 1 / 2;
  }

  .site-nav__book {
    grid-area: 1 / 3;
  }
}

.site-header__name {
  color: var(--text);
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--step-1);
  text-decoration: none;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  color: var(--text);
  text-decoration: none;
}

.site-nav a:hover {
  text-decoration: underline;
}

.site-nav__book:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.site-footer {
  padding-block: 2rem;
  border-top: 1px solid var(--line);
  background: var(--bg);
  color: var(--muted);
  font-size: var(--step--1);
}

.site-footer a {
  color: var(--accent);
}

/* ==========================================================================
   Hero: the listing at a glance
   ========================================================================== */

.hero {
  position: relative;
  padding-block: clamp(1.5rem, 3vw, 2.5rem) var(--section-space);
  overflow: hidden;
}

/* A constellation of code tokens drifts behind everything; main.js draws it
   and nudges it away from the pointer */
.hero__sky {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Fade the tokens out before the stats row */
.hero::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 0;
  height: 14rem;
  background: linear-gradient(to bottom, transparent, var(--bg) 85%);
  pointer-events: none;
}

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 3rem;
}

.hero__intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Status pill: main.js flips it to away outside Mon-Sat 9-6 Eastern */
.status {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 1rem 0.45rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
}

.status__dot {
  position: relative;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 60%, transparent);
}

.status__dot::before,
.status__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--accent);
  animation: dot-ping 2.2s ease-out infinite;
  opacity: 0;
}

.status__dot::after {
  animation-delay: 0.7s;
}

.status.is-away .status__dot {
  background: var(--amber);
}

.status.is-away .status__dot::before,
.status.is-away .status__dot::after {
  animation: none;
}

@keyframes dot-ping {
  0% { opacity: 0.9; scale: 1; }
  100% { opacity: 0; scale: 3; }
}

/* Green dots pulse: a soft ring grows out and fades. --pulse-base keeps
   any ring the dot already has; --pulse-size sets how far the ring grows. */
@keyframes dot-pulse {
  0% { box-shadow: var(--pulse-base, 0 0 0 0 transparent), 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  80%, 100% { box-shadow: var(--pulse-base, 0 0 0 0 transparent), 0 0 0 var(--pulse-size, 10px) transparent; }
}

.job__marker,
.flow__steps li::before,
.toolbox .toolbox__chips > li:has(.tool) .sticker::after {
  animation: dot-pulse 2.4s ease-out infinite;
}

/* Stagger the timeline so the dots don't all pulse at once */
.timeline > li:nth-child(2) .job__marker,
.flow__steps li:nth-child(2)::before { animation-delay: 0.3s; }
.timeline > li:nth-child(3) .job__marker,
.flow__steps li:nth-child(3)::before { animation-delay: 0.6s; }
.timeline > li:nth-child(4) .job__marker,
.flow__steps li:nth-child(4)::before { animation-delay: 0.9s; }
.timeline > li:nth-child(5) .job__marker,
.flow__steps li:nth-child(5)::before { animation-delay: 1.2s; }
.timeline > li:nth-child(n+6) .job__marker { animation-delay: 1.5s; }

.hero__name {
  margin-top: 1rem;
  font-size: var(--step-5);
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.hero__lead {
  max-width: 36ch;
  margin-top: 1rem;
  font-size: var(--step-1);
  line-height: 1.35;
}

/* Stock chip in the lead: symbol only until a quote arrives (see main.js) */
.ticker {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  vertical-align: 0.15em;
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
}

.ticker:hover {
  border-color: var(--accent);
}

.ticker__quote {
  display: inline-flex;
  gap: 0.4rem;
}

.ticker__quote[hidden] {
  display: none;
}

.ticker__chg {
  color: var(--muted);
}

.ticker[data-trend="up"] .ticker__chg {
  color: var(--accent);
}

.ticker[data-trend="down"] .ticker__chg {
  color: #B4382F;
}

.hero__tagline {
  margin-top: 0.75rem;
  color: var(--muted);
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--step-1);
  line-height: 1.15;
}

.hero__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.hero__facts li {
  display: flex;
  align-items: center;
  gap: 0.3em;
}

@media (max-width: 39.99rem) {
  .hero__facts {
    gap: 0.5rem 1.25rem;
  }

  .hero__facts li + li::before {
    display: none;
  }
}

.hero__facts li + li::before {
  content: "";
  width: 1px;
  height: 1em;
  margin-inline: 0.9rem;
  background: currentColor;
  opacity: 0.3;
}

.hero__facts .clock {
  font-variant-numeric: tabular-nums;
}

.stack {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
}

.stack__item {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border: 3px solid #fff;
  border-radius: 9px;
  background: var(--brand);
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14), 0 6px 12px -6px rgba(20, 24, 27, 0.4);
  color: var(--ink, #fff);
  transition: transform 0.2s var(--ease-out), box-shadow 0.2s ease;
}

.stack__item:hover {
  transform: translateY(-3px) rotate(-3deg);
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14), 0 12px 18px -8px rgba(20, 24, 27, 0.5);
}

.stack__item svg {
  width: 1.6rem;
  height: 1.6rem;
  fill: currentColor;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
  margin-top: 1.5rem;
}

.hero__link {
  font-weight: 700;
}

.hero__icon {
  display: inline-flex;
  color: var(--text);
}

.hero__icon:hover {
  color: var(--accent);
}

.hero__icon svg {
  display: block;
}

/* Photo beside the intro, editor band underneath */
.hero__top {
  display: grid;
  gap: 2rem;
}

.hero__side {
  display: grid;
  gap: 1.25rem;
}

.hero__photo {
  position: relative;
  margin: 0;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: var(--radius-s);
  background: var(--surface-2);
  box-shadow: 0 24px 48px -28px rgba(20, 24, 27, 0.35);
  transition: opacity 0.5s ease, translate 0.6s var(--ease-out), scale 0.6s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.hero__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}

.hero__photo.is-missing img {
  display: none;
}

.hero__photo .shot__missing {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.intro .hero__photo {
  opacity: 0;
  translate: 0 1.5rem;
  scale: 0.96;
}

.hero__editor {
  position: relative;
  display: grid;
  gap: 1rem;
}

/* The editor: a sheet of code lying on the photo, typed out on load */
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface);
  box-shadow: 0 20px 40px -24px rgba(20, 24, 27, 0.35);
  color: var(--text);
  transition: opacity 0.5s ease, translate 0.6s var(--ease-out), scale 0.6s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.intro .tile {
  opacity: 0;
  translate: 0 1.5rem;
  scale: 0.94;
}

.tile--term {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1.55;
}

.term__bar {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.55rem 1rem;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.72rem;
}

.term__bar em {
  color: var(--text);
  font-style: normal;
}

/* A note on the far side of the bar tying the code to the status pill */
.term__note {
  margin-left: auto;
  color: var(--accent);
  font-style: normal;
  white-space: nowrap;
}

.term__body {
  height: 13rem;
  margin: 0;
  padding: 0.9rem 1rem 1rem;
  overflow: hidden;
  font-size: 0.84rem;
  white-space: pre;
  tab-size: 2;
}

.term__lines .c { color: var(--code-cmt); font-style: italic; }
.term__lines .k { color: var(--code-kw); }
.term__lines .s { color: var(--code-str); }
.term__lines .n { color: var(--code-num); }

.term__lines::after {
  content: "";
  display: inline-block;
  width: 0.55em;
  height: 1em;
  margin-left: 0.1em;
  background: var(--accent);
  vertical-align: -0.15em;
  animation: caret 1s steps(2, start) infinite;
}

/* Highlights: free-standing numbers, no boxes */
.facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem 2rem;
  margin: 0;
  padding: 2rem 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
  line-height: 1.35;
}

.facts strong {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: var(--display-weight);
  line-height: 1;
}

@media (min-width: 64rem) {
  .hero__intro {
    padding-block: 0.5rem;
  }

  .hero__name {
    font-size: var(--step-5);
  }

  /* Intro on the left; the photo with the editor tucked under it on the right */
  .hero__top {
    grid-template-columns: minmax(0, 7.5fr) minmax(0, 4.5fr);
    column-gap: clamp(2.5rem, 5vw, 5rem);
    align-items: start;
  }

  /* A loose collage: the photo tilts one way, the editor tilts the other and
     hangs over the photo's bottom edge, spilling a little past the column */
  .hero__side {
    gap: 0;
    padding-top: 0.5rem;
  }

  .hero__photo {
    rotate: -1.5deg;
  }

  .hero__editor {
    z-index: 2;
    margin: -3.5rem 1rem 0 -4.5rem;
    rotate: 1.2deg;
  }

  .hero__editor .tile--term {
    box-shadow: 0 30px 60px -28px rgba(20, 24, 27, 0.5);
  }

  .term__body {
    height: 12.5rem;
    font-size: 0.72rem;
  }

  .facts {
    grid-template-columns: repeat(4, minmax(min-content, 1fr));
    column-gap: 0;
    margin-top: 3.5rem;
    border-top: 0;
  }

  .facts li {
    padding-inline: 1.5rem;
    border-left: 1px solid var(--line);
  }

  .facts li:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* Cards that rise into place as they scroll in */
.js .reveal-on-scroll {
  opacity: 0;
  translate: 0 1.5rem;
  transition: opacity 0.6s ease, translate 0.7s var(--ease-out);
}

.js .reveal-on-scroll.is-in {
  opacity: 1;
  translate: 0 0;
}

.reveal-on-scroll:nth-child(2) { transition-delay: 0.1s; }
.reveal-on-scroll:nth-child(3) { transition-delay: 0.2s; }
.reveal-on-scroll:nth-child(4) { transition-delay: 0.3s; }
.reveal-on-scroll:nth-child(5) { transition-delay: 0.4s; }

/* ==========================================================================
   Section heads (shared)
   ========================================================================== */

.section-head {
  display: grid;
  gap: 1rem;
  margin-bottom: clamp(3rem, 8vw, 6rem);
}

.section-head h2 {
  font-size: var(--step-4);
}

.section-head p {
  max-width: 38ch;
  font-size: var(--step-1);
  line-height: 1.4;
}

@media (min-width: 56rem) {
  .section-head {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: end;
    column-gap: 3rem;
  }
}

/* ==========================================================================
   Work: one viewer, many places
   ========================================================================== */

.work {
  padding-block: clamp(2rem, 5vw, 4rem) var(--section-space);
}

.viewer {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
}

.viewer > * {
  min-width: 0;
}

/* Project list: chips in a row on phones, a column beside the frame on desktop */
.viewer__list {
  display: flex;
  gap: 0.5rem;
  margin-inline: calc(-1 * var(--gutter));
  padding-inline: var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
}

.viewer__list::-webkit-scrollbar {
  display: none;
}

/* Each project is a row with a rule under it; the chosen one is marked in
   the accent, with no filled button */
.viewer__tab {
  display: grid;
  flex: none;
  gap: 0.1rem;
  padding: 0.7rem 1rem 0.7rem 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text);
  font: inherit;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.viewer__tab strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: var(--display-weight);
  transition: color 0.2s ease;
}

.viewer__tab span {
  color: var(--muted);
  font-size: var(--step--1);
}

.viewer__tab:hover {
  border-color: var(--line);
}

.viewer__tab[aria-selected="true"] {
  border-color: var(--accent);
}

.viewer__tab[aria-selected="true"] strong {
  color: var(--accent);
}

.browser {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface);
}

.browser__bar {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  min-height: 2.5rem;
  padding: 0.35rem 0.9rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.78rem;
}

.browser__url {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.browser__viewport {
  aspect-ratio: 16 / 10;
  background: var(--wf-fill);
}

/* The live site is inert until the viewer asks for it (see main.js), so a
   scroll down the page never gets trapped inside the frame */
.browse {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 1.25rem;
  border: 0;
  background: linear-gradient(transparent 60%, rgba(0, 0, 0, 0.6));
  color: var(--on-accent);
  font: inherit;
  cursor: pointer;
}

.browse__label {
  display: inline-block;
  padding: 0.6rem 1.25rem;
  border-radius: var(--radius-s);
  background: var(--accent);
  font-weight: 700;
  transition: transform 0.15s ease;
}

.browse:hover .browse__label {
  transform: translateY(-2px);
}

.browse:focus-visible {
  outline-offset: -4px;
}

.viewer__stage.is-browsing .browse {
  display: none;
}

.browser__done {
  margin-left: auto;
  padding: 0.2rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  cursor: pointer;
}

.browser__done:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.viewer__stage:not(.is-browsing) .browser__done {
  display: none;
}

/* Details for the selected project */
.viewer__panel {
  display: grid;
  gap: 1.75rem;
  margin-top: 1.75rem;
}

.viewer__panel[hidden] {
  display: none;
}

.place__title {
  font-size: var(--step-3);
}

.place__where {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  color: var(--muted);
}

.place__logo {
  display: block;
  width: auto;
  height: 1.35rem;
}

.place__summary {
  margin-top: 1rem;
  font-size: var(--step-1);
  line-height: 1.45;
}

.place__visit {
  margin-top: 1.5rem;
}

.place__facts {
  display: grid;
  align-content: start;
  gap: 1rem;
  margin: 0;
}

/* A code excerpt runs the full width under the panel's two columns */
.viewer__panel > .listing {
  grid-column: 1 / -1;
  margin-top: 0;
}

.place__facts div {
  display: grid;
  gap: 0.2rem;
  padding-left: 1rem;
  border-left: 3px solid var(--accent);
}

.place__facts dt {
  font-size: var(--step--1);
  font-weight: 700;
}

.place__facts dd {
  margin: 0;
  line-height: 1.5;
}

@media (min-width: 64rem) {
  .viewer {
    grid-template-columns: minmax(14rem, 3fr) minmax(0, 9fr);
    column-gap: clamp(1.5rem, 3vw, 3rem);
    align-items: start;
  }

  .viewer__list {
    position: sticky;
    top: 5.5rem;
    flex-direction: column;
    gap: 0;
    margin: 0;
    padding: 0;
    overflow: visible;
  }

  /* Stacked, the marker moves to the left edge */
  .viewer__tab {
    padding: 0.9rem 0 0.9rem 1.1rem;
    border-bottom: 0;
    border-left: 2px solid transparent;
  }

  .viewer__panel {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    column-gap: clamp(2rem, 4vw, 4rem);
  }
}

/* ==========================================================================
   Side projects: case studies
   ========================================================================== */

.projects {
  padding-block: var(--section-space);
}

.study {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
}

.study > * {
  min-width: 0;
}

.study + .study {
  margin-top: clamp(4rem, 8vw, 7rem);
  padding-top: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid var(--line);
}

.study__facts a {
  font-weight: 700;
}

.study__kicker {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
}

.study__intro h3 {
  margin-top: 0.5rem;
  font-size: var(--step-3);
}

/* A wordmark standing in for the heading text */
.study__logo {
  display: block;
  width: auto;
  height: 3.4rem;
  margin-block: 0.35rem;
}

.study__lead {
  margin-top: 1rem;
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--step-1);
  line-height: 1.25;
}

.study__intro > p:not(.study__kicker):not(.study__lead) {
  max-width: 62ch;
  margin-top: 1rem;
  line-height: 1.55;
}

.study__stack {
  margin-top: 1.5rem;
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

/* How it works: a stepper on a rail, one row per step, no panel around it */
.flow {
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.flow__title {
  margin-bottom: 0.5rem;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
}

.flow__steps {
  position: relative;
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The rail the markers sit on */
.flow__steps::before {
  content: "";
  position: absolute;
  top: 1.2rem;
  bottom: 1.2rem;
  left: calc(0.5rem - 1px);
  width: 2px;
  background: color-mix(in srgb, var(--accent) 35%, transparent);
}

.flow__steps li {
  position: relative;
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr);
  column-gap: 1rem;
  row-gap: 0.15rem;
  padding-block: 0.7rem;
  line-height: 1.4;
}

.flow__steps li::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: start;
  width: 1rem;
  height: 1rem;
  margin-top: 0.15rem;
  border: 3px solid var(--accent);
  border-radius: 50%;
  background: var(--bg);
}

.flow__steps li:last-child::before {
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
  --pulse-base: 0 0 0 4px var(--accent-soft);
  --pulse-size: 12px;
}

.flow__steps strong {
  grid-column: 2;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: var(--display-weight);
}

.flow__steps span {
  grid-column: 2;
  color: var(--muted);
  font-size: var(--step--1);
}

.flow code {
  font-family: var(--font-mono);
  font-size: 0.85em;
}

.study__code {
  margin: 0;
}

.study__facts {
  display: grid;
  gap: 1rem;
  margin: 0;
}

.study__facts div {
  display: grid;
  gap: 0.2rem;
  padding-left: 1rem;
  border-left: 3px solid var(--accent);
}

.study__facts dt {
  font-size: var(--step--1);
  font-weight: 700;
}

.study__facts dd {
  margin: 0;
  line-height: 1.5;
}

@media (min-width: 56rem) {
  /* Wide enough for the step name and its description to share a row */
  .flow__steps li {
    grid-template-columns: 1rem 10rem minmax(0, 1fr);
    column-gap: 1.25rem;
    align-items: baseline;
    padding-block: 0.8rem;
  }

  .flow__steps li::before {
    grid-row: 1;
    align-self: center;
    margin-top: 0;
  }

  .flow__steps strong {
    grid-column: 2;
  }

  .flow__steps span {
    grid-column: 3;
    font-size: var(--step-0);
  }

  .study__facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 2rem;
  }
}

@media (min-width: 64rem) {
  .study {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: clamp(2rem, 4vw, 4rem);
    align-items: start;
  }

  /* The title and description stay put while the steps, code and facts
     scroll past, then give way to the next project */
  .study__intro {
    position: sticky;
    top: 5.5rem;
    grid-row: 1 / 3;
    align-self: start;
  }

  .study .flow,
  .study__code,
  .study__facts {
    grid-column: 2;
  }

  .study__facts {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }
}

/* ==========================================================================
   Experience: a vertical timeline
   ========================================================================== */

.experience {
  padding-block: var(--section-space);
  background: var(--bg-2);
}

.timeline {
  position: relative;
  display: grid;
  gap: 2.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One continuous line behind the markers */
.timeline::before {
  content: "";
  position: absolute;
  top: 0.75rem;
  bottom: 1rem;
  left: calc(0.625rem - 1px);
  width: 2px;
  background: var(--line);
}

.job {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  column-gap: 1rem;
}

.job__dates {
  grid-column: 2;
  margin-bottom: 0.4rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.job__marker {
  position: relative;
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: start;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.15rem;
  border: 3px solid var(--accent);
  border-radius: 50%;
  background: var(--bg-2);
}

.job--now .job__marker {
  background: var(--accent);
  box-shadow: 0 0 0 5px var(--accent-soft);
  --pulse-base: 0 0 0 5px var(--accent-soft);
  --pulse-size: 14px;
}

.job__body {
  grid-column: 2;
}

.job__body h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  font-size: var(--step-2);
}

.job__now {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
}

.job__org {
  margin-top: 0.3rem;
  color: var(--muted);
  font-weight: 600;
}

.job__logo {
  display: inline-block;
  width: auto;
  height: 1.5rem;
  margin-top: 0.15rem;
  vertical-align: middle;
}

/* The SocialCroc mark has a low wordmark under the croc, so it needs more height to read */
.job__logo--tall {
  height: 1.9rem;
}

.job__points {
  display: grid;
  gap: 0.6rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  line-height: 1.5;
}

.job__points li {
  position: relative;
  padding-left: 1.25rem;
}

.job__points li::before {
  content: "";
  position: absolute;
  top: 0.7em;
  left: 0;
  width: 0.6rem;
  height: 3px;
  background: var(--accent);
}

.job--edu .job__body h3 {
  font-size: var(--step-1);
}

.job--edu .job__marker {
  width: 0.9rem;
  height: 0.9rem;
  margin: 0.3rem 0 0 0.175rem;
  border-width: 2px;
}

@media (min-width: 56rem) {
  .job {
    grid-template-columns: 11rem 1.25rem minmax(0, 1fr);
    column-gap: 1.5rem;
  }

  .job__dates {
    grid-column: 1;
    grid-row: 1;
    margin: 0.55rem 0 0;
    text-align: right;
  }

  .job__marker {
    grid-column: 2;
    grid-row: 1;
    margin-top: 0.55rem;
  }

  .job__body {
    grid-column: 3;
    grid-row: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    column-gap: 3rem;
  }

  .job__body h3 {
    grid-column: 1;
  }

  .job__org {
    grid-column: 1;
  }

  .job__points {
    grid-column: 2;
    grid-row: 1 / 3;
    margin-top: 0.4rem;
  }

  .timeline::before {
    top: 1rem;
    left: calc(11rem + 1.5rem + 0.625rem - 1px);
  }
}

/* ==========================================================================
   Toolkit: a toolbox of chips with physics, and magnets to sort them
   ========================================================================== */

/* Shared by the Toolkit and How a website works: a monospace rail of
   buttons, and a serif readout underneath */
.rail {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 1.1rem;
}

.rail__label {
  min-width: 5.5rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.magnet {
  padding: 0.35rem 0 0.2rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.magnet:hover {
  border-color: var(--line);
}

.magnet[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

.magnet--clear,
.magnet--shake {
  color: var(--muted);
  font-weight: 400;
}

.magnet--clear:hover,
.magnet--shake:hover {
  color: var(--text);
}

.magnet[hidden] {
  display: none;
}

.readout {
  max-width: 60ch;
  min-height: 2.6em;
  margin: 0;
  color: var(--muted);
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.3;
}

.readout strong {
  color: var(--text);
  font-weight: var(--display-weight);
}

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

/* ==========================================================================
   Toolkit: a pile of laptop stickers
   ========================================================================== */

.amenities {
  padding-block: var(--section-space);
}

.toolbox {
  display: grid;
  gap: 1.25rem;
}

.toolbox__magnets {
  display: grid;
  gap: 0.35rem;
}

/* The arena: a wrapped list until main.js switches physics on, then a box
   the stickers drop into, ruled top and bottom so the pile has a floor */
.toolbox__arena {
  position: relative;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 2px solid var(--rule);
  touch-action: pan-y;
}

.toolbox .toolbox__chips {
  gap: 0.6rem;
  padding: 1.5rem 0 1.75rem;
}

.toolbox .toolbox__chips > li {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 0.95rem;
  user-select: none;
  transition: opacity 0.35s ease, filter 0.35s ease;
}

/* A sticker: die cut with a white edge, the brand color inside, the mark
   and the name in whichever ink reads on it */
.tools .sticker {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.95rem 0.5rem 0.65rem;
  border: 3px solid #fff;
  border-radius: 10px;
  background: var(--brand);
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14), 0 6px 12px -6px rgba(20, 24, 27, 0.45);
  color: var(--ink, #fff);
  font: inherit;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.005em;
  cursor: default;
  transition: box-shadow 0.25s ease, transform 0.2s ease;
}

.tools button.sticker {
  cursor: pointer;
}

.tools .sticker__mark {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
}

.tools .sticker__mark svg {
  width: 1.4rem;
  height: 1.4rem;
  fill: currentColor;
}

.tools .sticker__mark--mono {
  width: auto;
  min-width: 1.5rem;
  padding: 0 0.3rem;
  border: 1.5px solid currentColor;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.35rem;
}

.tools .sticker__name {
  white-space: nowrap;
}

/* Stories: a small corner tab marks the stickers that have one */
.toolbox .toolbox__chips > li:has(.tool) .sticker {
  position: relative;
}

.toolbox .toolbox__chips > li:has(.tool) .sticker::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -3px;
  width: 9px;
  height: 9px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14);
  --pulse-base: 0 0 0 1px rgba(20, 24, 27, 0.14);
  --pulse-size: 6px;
}

.toolbox .toolbox__chips > li.is-active .sticker {
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14), 0 0 0 4px var(--accent-soft), 0 10px 20px -8px rgba(20, 24, 27, 0.5);
}

.toolbox .toolbox__chips > li.is-dim {
  opacity: 0.28;
  filter: saturate(0.15);
}

.toolbox.is-physics .toolbox__chips {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
}

.toolbox.is-physics .toolbox__chips > li {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  transform: translate(-999px, -999px);
  cursor: grab;
  will-change: transform;
}

.toolbox.is-physics .toolbox__chips > li.is-held {
  z-index: 3;
  cursor: grabbing;
}

.toolbox.is-physics .toolbox__chips > li.is-held .sticker {
  box-shadow: 0 0 0 1px rgba(20, 24, 27, 0.14), 0 22px 30px -12px rgba(20, 24, 27, 0.55);
}

.toolbox.is-physics .sticker {
  cursor: inherit;
}

.toolbox.is-physics button.sticker {
  cursor: pointer;
}

@media (max-width: 40rem) {
  .toolbox .toolbox__chips > li {
    font-size: 0.85rem;
  }

  .sticker {
    padding: 0.4rem 0.75rem 0.4rem 0.55rem;
  }
}

/* ==========================================================================
   How a website works: a page pulled apart into its layers
   ========================================================================== */

.anatomy {
  padding-block: var(--section-space);
  border-top: 1px solid var(--line);
}

.anatomy__inner {
  display: grid;
  gap: 1.5rem;
}

/* The exploded view: the stack on the left, the layers named on the right
   in build order, and one leader line for the layer being pointed at */
.exploded {
  position: relative;
  display: grid;
  gap: 1.5rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.leaders {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.leaders path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
}

.leaders circle {
  fill: var(--accent);
}

.leaders path,
.leaders circle {
  opacity: 0;
  transition: opacity 0.2s ease;
}

.leaders.is-on path,
.leaders.is-on circle {
  opacity: 1;
}

/* The scene: a tilted stack of sheets, each one a layer of the same page */
.scene {
  --scale: 0.6;
  position: relative;
  height: 24rem;
  overflow: visible;
  perspective: 1500px;
  perspective-origin: 50% 40%;
}

.sheets {
  --gap: 84px;
  --rx: 58deg;
  --rz: -34deg;
  --lift: 200px;
  --zoom: 1;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 340px;
  height: 230px;
  margin: -115px 0 0 -170px;
  transform: translateY(calc(var(--lift) * var(--scale))) scale(calc(var(--scale) * var(--zoom))) rotateX(var(--rx)) rotateZ(var(--rz));
  transform-style: preserve-3d;
  transition: transform 0.7s var(--ease-out), opacity 0.35s ease;
}

/* Folded: the sheets close up into one page and it comes closer. The gap
   is a hair, so a part drawn on two layers (the button's fill, label and
   link) reads as one and not as a doubled, offset copy */
.sheets.is-folded {
  --gap: 0.4px;
  --lift: 10px;
  --zoom: 1.6;
}

.layer {
  --out: 0px;
  --up: 0px;
  position: absolute;
  inset: 0;
  border: 1px solid color-mix(in srgb, var(--text) 32%, transparent);
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 18px 26px -16px rgba(20, 24, 27, 0.4);
  transform: translate3d(var(--out), 0, calc(var(--i) * var(--gap) + var(--up)));
  transform-style: preserve-3d;
  transition: transform 0.55s var(--ease-out), opacity 0.45s ease, border-color 0.3s ease, background-color 0.3s ease;
}

/* Folding and unfolding, the sheets move one after another */
.sheets.is-animating .layer,
.js .sheets:not(.is-in) .layer {
  transition-delay: calc(var(--i) * 50ms);
  transition-duration: 0.8s;
}

.layer--plate {
  background: var(--bg-2);
}

/* Rising in: the sheets start folded and open up */
.js .sheets:not(.is-in) {
  --gap: 0px;
  --lift: 10px;
}

.js .sheets:not(.is-in) .layer {
  opacity: 0;
}

.layer.is-out {
  --out: -160px;
  opacity: 0;
  pointer-events: none;
}

.sheets.has-focus .layer:not(.is-focus) {
  opacity: 0.35;
}

.sheets.has-focus .layer.is-focus {
  border-color: var(--accent);
}

.sheets.has-lift .layer.is-focus {
  --up: 26px;
}

.sheets.is-folded .layer.is-focus {
  --up: 0px;
}

/* Folded, the wireframe, the grid, the hosting notes, the logic layer's
   pointers and the contact form (which lives further down the real page)
   step aside so what remains reads as the finished top of this page */
.sheets.is-folded .blk--outline,
.sheets.is-folded .blk--el,
.sheets.is-folded .blk--grid,
.sheets.is-folded .blk--swatch,
.sheets.is-folded .blk--aa,
.sheets.is-folded .blk--aa2,
.sheets.is-folded .blk--aa3,
.sheets.is-folded .blk--tag,
.sheets.is-folded .layer--plate .blk--text,
.sheets.is-folded .layer--plate .blk--tasks,
.sheets.is-folded .layer--plate .blk--edge,
.sheets.is-folded .layer--plate .blk--dot,
.sheets.is-folded .blk--ring,
.sheets.is-folded .blk--cursor,
.sheets.is-folded .blk--countring,
.sheets.is-folded .layer[data-layer="marketing"] .blk--input,
.sheets.is-folded .layer[data-layer="marketing"] .blk--fill-accent {
  opacity: 0;
}

/* Folded, the lowest sheet in use is the page and the rest go clear, so
   every layer shows through as one drawing */
.sheets.is-folded .layer:not(.is-out) {
  background: #fff;
  box-shadow: 0 40px 50px -30px rgba(20, 24, 27, 0.35);
}

.sheets.is-folded .layer:not(.is-out) ~ .layer:not(.is-out) {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}

/* Where the leader lands: the sheet's bottom right corner, which the tilt
   turns into its rightmost point, so the line reaches it over open space */
.layer__pin {
  position: absolute;
  top: 100%;
  right: 0;
  width: 1px;
  height: 1px;
}

/* Each sheet carries its name, printed just above its top edge */
.layer__name {
  position: absolute;
  top: -17px;
  left: 0;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.04em;
  transition: color 0.25s ease;
}

.layer.is-focus .layer__name {
  color: var(--accent);
}

.sheets.is-folded .layer__name {
  opacity: 0;
}

/* The blocks each sheet is drawn with */
.blk {
  position: absolute;
  display: block;
  box-sizing: border-box;
  border-radius: 2px;
  font-style: normal;
  transform: rotate(var(--r, 0deg));
  transition: opacity 0.3s ease;
}

/* This page's parts */
.blk--pillbg {
  border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
  border-radius: 999px;
  background: #fff;
}

.blk--pilltext {
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 6px;
  font-weight: 700;
  line-height: 11px;
}

.blk--brand {
  color: var(--text);
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 500;
  line-height: 14px;
}

.blk--nav {
  color: var(--text);
  font-family: var(--font-body);
  font-size: 6px;
  line-height: 10px;
  white-space: pre;
}

.blk--btntext {
  color: #fff;
  font-family: var(--font-body);
  font-size: 6.5px;
  font-weight: 700;
  line-height: 13px;
  text-align: center;
}

.blk--cta {
  border-radius: 2px;
  background: var(--accent);
  color: #fff;
  font-family: var(--font-body);
  font-size: 6.5px;
  font-weight: 700;
  line-height: 13px;
  text-align: center;
}

.blk--link {
  color: var(--accent);
  font-family: var(--font-body);
  font-size: 6.5px;
  font-weight: 700;
  line-height: 9px;
  text-decoration: underline;
}

.blk--tagline {
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 7px;
  line-height: 10px;
  white-space: nowrap;
}

.blk--mono {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 5.5px;
  line-height: 8px;
  white-space: pre;
}

.blk--stat {
  color: var(--text);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 500;
  line-height: 12px;
}

.blk--statnote {
  overflow: hidden;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 4.2px;
  line-height: 5.5px;
}

/* The hero's lead, set small; the gap holds the stock chip's place */
.blk--lead {
  overflow: hidden;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 5.4px;
  line-height: 6.5px;
}

.blk__gap {
  display: inline-block;
  width: 32px;
  height: 5px;
  vertical-align: middle;
}

.blk--ticker {
  border: 0.5px solid color-mix(in srgb, var(--text) 25%, transparent);
  border-radius: 1.5px;
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 4.2px;
  font-weight: 700;
  line-height: 6px;
  text-align: center;
  white-space: nowrap;
}

.blk--sheet {
  border: 1px solid color-mix(in srgb, var(--text) 22%, transparent);
  background: #fff;
  box-shadow: 0 6px 10px -6px rgba(20, 24, 27, 0.4);
}

.blk--headshot {
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: 0 8px 14px -8px rgba(20, 24, 27, 0.5);
}

.blk--headshot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}

.blk--sq svg {
  display: block;
  width: 100%;
  height: 100%;
  padding: 1.5px;
  box-sizing: border-box;
  fill: currentColor;
}

.blk--sq {
  border: 1.5px solid #fff;
  border-radius: 3px;
  box-shadow: 0 0 0 0.5px rgba(20, 24, 27, 0.2);
}

.blk--glyph {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 7px;
  font-weight: 600;
  line-height: 10px;
  opacity: 0.6;
}

.blk--caret {
  background: var(--accent);
  animation: caret 1s steps(2, start) infinite;
}

.blk--countring {
  border: 1.5px dashed var(--accent);
  border-radius: 4px;
}

.blk--clock {
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 5.5px;
  font-weight: 700;
  line-height: 8px;
}

.blk--aa2 {
  color: var(--text);
  font-family: var(--font-body);
  font-size: 7px;
  line-height: 12px;
}

.blk--aa3 {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 6px;
  line-height: 12px;
}

.blk--outline {
  border: 1px dashed color-mix(in srgb, var(--text) 45%, transparent);
  border-radius: 3px;
}

.blk--fill-accent { background: var(--accent); }
.blk--fill-soft { background: var(--accent-soft); }
.blk--fill-2 { background: color-mix(in srgb, var(--text) 7%, transparent); }
.blk--bar-dark { background: var(--text); }
.blk--bar-muted { background: color-mix(in srgb, var(--text) 35%, transparent); }
.blk--bar-light { background: color-mix(in srgb, var(--text) 20%, #fff); }

.blk--photo {
  background:
    radial-gradient(circle at 70% 28%, #F2C98A 0 9px, transparent 10px),
    linear-gradient(160deg, #7EE2B8 0%, #0B7C61 60%, #085E49 100%);
}

.blk--photo::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 42%;
  background: linear-gradient(to top, #14181B, transparent);
  clip-path: polygon(0 100%, 30% 35%, 52% 70%, 74% 20%, 100% 100%);
  opacity: 0.75;
}

.blk--ring {
  border: 2px solid var(--accent);
  border-radius: 50%;
  opacity: 0.7;
}

.blk--cursor {
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 18'%3E%3Cpath d='M1 1l12 8-5 1 3 6-2 1-3-6-4 4z' fill='%2314181B' stroke='%23fff' stroke-width='1'/%3E%3C/svg%3E");
}

.blk--toggle {
  background: var(--accent);
  border-radius: 999px;
}

.blk--knob {
  background: #fff;
  border-radius: 50%;
}

.blk--code {
  padding: 6px 6px 0;
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 4.2px;
  font-weight: 600;
  line-height: 7.5px;
  white-space: pre;
  overflow: hidden;
}

.blk--tag {
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 7px;
  line-height: 8px;
  text-align: center;
}

.blk--chart {
  background: repeating-linear-gradient(90deg, var(--accent) 0 9px, transparent 9px 14px);
  clip-path: polygon(0 60%, 14px 60%, 14px 30%, 28px 30%, 28px 75%, 42px 75%, 42px 10%, 56px 10%, 56px 45%, 72px 45%, 72px 100%, 0 100%);
}

.blk--input {
  border: 1px solid color-mix(in srgb, var(--text) 35%, transparent);
  background: #fff;
}

.blk--url {
  border: 1px solid color-mix(in srgb, var(--text) 25%, transparent);
  border-radius: 999px;
  background: #fff;
}

.blk--url::before {
  content: "https://";
  position: absolute;
  top: 0;
  left: 8px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 7px;
  line-height: 10px;
}

.blk--dot {
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.blk--text {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 8px;
  line-height: 14px;
  white-space: pre;
}

.blk--el {
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 7.5px;
  line-height: 10px;
  white-space: nowrap;
}

.blk--swatch {
  border: 1px solid rgba(20, 24, 27, 0.15);
  border-radius: 2px;
}

.blk--aa {
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 16px;
}

.blk--h1 {
  color: var(--text);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  line-height: 17px;
  letter-spacing: -0.01em;
  white-space: normal;
}

.blk--cap {
  color: var(--text);
  font-family: var(--font-body);
  font-size: 7px;
  font-weight: 700;
  line-height: 10px;
  white-space: nowrap;
}

.blk--wdots {
  background: radial-gradient(circle at 3px 50%, color-mix(in srgb, var(--text) 30%, transparent) 0 2px, transparent 2.5px) 0 0 / 9px 100% repeat-x;
}

.blk--tasks {
  background:
    radial-gradient(circle at 3px 50%, var(--accent) 0 1.5px, transparent 2px) 0 0 / 19px 100% repeat-x,
    linear-gradient(color-mix(in srgb, var(--text) 30%, transparent), color-mix(in srgb, var(--text) 30%, transparent)) 7px 4px / 10px 2px repeat-x;
  background-repeat: repeat-x;
}

.blk--edge {
  background: radial-gradient(circle at 5px 50%, var(--accent) 0 2px, var(--accent-soft) 2.5px 4px, transparent 4.5px) 0 0 / 14px 100% repeat-x;
}

.blk--chip {
  border-radius: 3px;
  background: linear-gradient(135deg, #2A3238, #14181B);
}

.blk--chip::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 4px;
  width: 8px;
  height: 6px;
  border-radius: 1px;
  background: #F2C98A;
}

.blk--chip::after {
  content: "•••• 4242";
  position: absolute;
  right: 4px;
  bottom: 1px;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 5px;
  line-height: 6px;
}

.blk--play {
  border: 2px solid var(--text);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85) no-repeat 55% 50% / 10px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M1 1l8 5-8 5z' fill='%2314181B'/%3E%3C/svg%3E");
}

.blk--mark {
  border-radius: 2px;
  background: var(--accent);
}

.blk--mark::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: #fff;
}

/* Assets: a row of little icons where the button sits */
.blk--icons {
  background: radial-gradient(circle at 8px 50%, var(--accent-deep) 0 3.5px, transparent 4px) 0 0 / 16px 100% repeat-x;
  opacity: 0.6;
}

.blk--menu {
  border: 1px solid color-mix(in srgb, var(--text) 30%, transparent);
  border-radius: 3px;
  background:
    linear-gradient(color-mix(in srgb, var(--text) 55%, transparent), color-mix(in srgb, var(--text) 55%, transparent)) 8px 8px / 36px 3px no-repeat,
    linear-gradient(color-mix(in srgb, var(--text) 30%, transparent), color-mix(in srgb, var(--text) 30%, transparent)) 8px 17px / 44px 3px no-repeat,
    linear-gradient(color-mix(in srgb, var(--text) 30%, transparent), color-mix(in srgb, var(--text) 30%, transparent)) 8px 26px / 28px 3px no-repeat,
    #fff;
  box-shadow: 0 4px 8px -4px rgba(20, 24, 27, 0.4);
}

.blk--db {
  border: 1.5px solid var(--text);
  border-radius: 50% / 30%;
  background:
    linear-gradient(var(--text), var(--text)) 0 4px / 100% 1px no-repeat,
    linear-gradient(var(--text), var(--text)) 0 8px / 100% 1px no-repeat;
  opacity: 0.8;
}

.blk--term {
  border-radius: 3px;
  background: #14181B;
  color: #7EE2B8;
  font-family: var(--font-mono);
  font-size: 7.5px;
  line-height: 22px;
  text-indent: 6px;
  white-space: nowrap;
}

.blk--ad {
  border: 1px dashed color-mix(in srgb, var(--text) 45%, transparent);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 7px;
  line-height: 10px;
  text-align: center;
}

.blk--grid {
  background: repeating-linear-gradient(90deg, rgba(11, 124, 97, 0.07) 0 20px, transparent 20px 25px);
  border-radius: 0;
}

/* The layers, named from the ground up. Each group also holds what the
   layer is on this page and what I do for you on it; with JS those lines
   are read out once, under the stack, so the list stays seven names */
.layers {
  display: grid;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.layers__group {
  display: grid;
  gap: 0.3rem;
  padding: 0.55rem 0 0.55rem 1rem;
  border-left: 2px solid transparent;
  transition: border-color 0.25s ease, opacity 0.35s ease;
}

.layers__group.is-focus {
  border-color: var(--accent);
}

.layer-btn {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.layer-btn strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: var(--display-weight);
  line-height: 1.1;
}

.layer-btn span {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.layer-btn[aria-pressed="true"] strong {
  color: var(--accent);
}

.layers__what {
  max-width: 50ch;
  color: var(--muted);
  font-size: var(--step--1);
  line-height: 1.45;
}

/* What I do for you: the line that matters, under a heavy accent rule */
.layers__me {
  display: grid;
  gap: 0.15rem;
  max-width: 50ch;
  margin-top: 0.35rem;
  padding: 0.5rem 0 0.1rem 0.9rem;
  border-left: 3px solid var(--accent);
  color: var(--text);
  font-size: var(--step-0);
  line-height: 1.45;
}

.layers__me span {
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
}

.js .layers__what,
.js .layers__me {
  display: none;
}

/* The preview: the focused sheet flat and enlarged over the dimmed stack */
.preview {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0.75rem;
  opacity: 0;
  pointer-events: none;
  transform: translateY(12px);
  transition: opacity 0.3s ease, transform 0.35s var(--ease-out);
}

.scene.is-previewing .preview {
  opacity: 1;
  transform: translateY(0);
}

.scene.is-previewing .sheets {
  opacity: 0.16;
}

.preview__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.2rem 0.75rem;
  max-width: calc(340px * var(--pz, 1.3));
  text-align: center;
}

.preview__head strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: var(--display-weight);
  line-height: 1.1;
}

.preview__head span {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.preview__sheet {
  position: relative;
  width: 340px;
  height: 230px;
  border: 1px solid color-mix(in srgb, var(--text) 32%, transparent);
  background: #fff;
  box-shadow: 0 30px 50px -30px rgba(20, 24, 27, 0.45);
  transform: scale(var(--pz, 1.3));
  transform-origin: 50% 0;
  margin-bottom: calc(230px * (var(--pz, 1.3) - 1));
  overflow: visible;
}

.preview__sheet--plate {
  background: var(--bg-2);
}

/* Callouts sit in the margins either side of the sheet and name the parts,
   each joined to its part by a thin line */
.callout {
  position: absolute;
  z-index: 2;
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 7.5px;
  font-weight: 700;
  line-height: 12px;
  white-space: nowrap;
  pointer-events: none;
}

.callout--left {
  right: calc(100% + 12px);
  text-align: right;
}

.callout--right {
  left: calc(100% + 12px);
}

.preview__lines {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.preview__lines path {
  fill: none;
  stroke: color-mix(in srgb, var(--accent) 55%, transparent);
  stroke-width: 0.75;
}

@media (max-width: 40rem) {
  .callout,
  .preview__lines {
    display: none;
  }
}

/* The preview plays the layer: parts arrive in order, then each layer's
   own motion shows what it does */
.preview__sheet .blk {
  animation: blk-in 0.45s var(--ease-out) both;
  animation-delay: calc(var(--n, 0) * 60ms);
}

@keyframes blk-in {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}

/* Structure: the outlines draw themselves */
.preview__sheet[data-layer="structure"] .blk--outline {
  animation: blk-in 0.45s var(--ease-out) both, draw 0.9s var(--ease-out) both;
  animation-delay: calc(var(--n, 0) * 90ms);
}

@keyframes draw {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

/* Style: the grid flashes, then the paint goes on */
.preview__sheet[data-layer="style"] .blk--grid {
  animation: blk-in 0.45s both, gridflash 1.8s 0.3s ease both;
}

@keyframes gridflash {
  30% { opacity: 1; background: repeating-linear-gradient(90deg, rgba(11, 124, 97, 0.22) 0 20px, transparent 20px 25px); }
  100% { opacity: 1; }
}

/* Content: the headline types itself and the copy fills in */
.preview__sheet[data-layer="content"] .blk--lead {
  animation: blk-in 0.3s both, typein 1.2s 0.9s var(--ease-out) both;
}

.preview__sheet[data-layer="content"] .blk--h1 {
  animation: blk-in 0.3s both, typein 0.9s 0.4s steps(10) both;
}

@keyframes typein {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

.preview__sheet[data-layer="content"] .blk--bar-muted {
  transform-origin: left;
  animation: blk-in 0.3s both, widen 0.8s var(--ease-out) both;
  animation-delay: calc(0.9s + var(--n, 0) * 60ms);
}

@keyframes widen {
  from { transform: scaleX(0); }
  to { transform: none; }
}

/* Assets: the image settles into place */
.preview__sheet[data-layer="assets"] .blk--headshot {
  animation: blk-in 0.4s both, settle 1.4s var(--ease-out) both;
}

@keyframes settle {
  from { transform: rotate(var(--r, 0deg)) scale(1.08); filter: saturate(0); }
  to { transform: rotate(var(--r, 0deg)); filter: none; }
}

/* Logic: the cursor clicks the button, the menu opens, the switch flips */
.preview__sheet[data-layer="logic"] .blk--cursor {
  animation: blk-in 0.4s both, click 2.8s 1s ease-in-out infinite;
}

@keyframes click {
  0%, 15% { transform: translate(18px, 14px); }
  40%, 55% { transform: translate(0, 0) scale(0.92); }
  85%, 100% { transform: translate(18px, 14px); }
}

.preview__sheet[data-layer="logic"] .blk--ring {
  animation: blk-in 0.4s both, ripple 2.8s 1s ease-out infinite;
}

@keyframes ripple {
  0%, 42% { transform: scale(0.3); opacity: 0; }
  50% { transform: scale(0.5); opacity: 0.9; }
  80%, 100% { transform: scale(1.7); opacity: 0; }
}

.preview__sheet[data-layer="logic"] .blk--menu {
  transform-origin: top;
  animation: blk-in 0.4s both, drop 2.8s 1s ease-in-out infinite;
}

@keyframes drop {
  0%, 8% { transform: scaleY(0); opacity: 0; }
  22%, 78% { transform: none; opacity: 1; }
  92%, 100% { transform: scaleY(0); opacity: 0; }
}

.preview__sheet[data-layer="logic"] .blk--knob {
  animation: blk-in 0.4s both, flip 2.8s 1s ease-in-out infinite;
}

@keyframes flip {
  0%, 35% { transform: translateX(0); }
  45%, 85% { transform: translateX(-14px); }
  95%, 100% { transform: translateX(0); }
}

.preview__sheet[data-layer="logic"] .blk--code {
  animation: blk-in 0.4s both, typein 1.6s 0.6s steps(34) both;
}

.preview__sheet[data-layer="logic"] .blk--clock {
  animation: blk-in 0.4s both, blink 1s 1.2s ease-in-out 2;
}

/* Marketing: the form fills and hands off */
.preview__sheet[data-layer="marketing"] .blk--chart {
  transform-origin: bottom;
  animation: grow 1.2s 0.3s var(--ease-out) both;
}

@keyframes grow {
  from { transform: scaleY(0); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.preview__sheet[data-layer="marketing"] .blk--input::after {
  content: "";
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 3px;
  width: 0;
  background: color-mix(in srgb, var(--text) 40%, transparent);
  animation: fillin 0.9s 1.2s steps(8) both;
}

.preview__sheet[data-layer="marketing"] .blk--input + .blk--input::after {
  animation-delay: 2s;
}

@keyframes fillin {
  to { width: 62%; }
}

.preview__sheet[data-layer="marketing"] .blk--cta {
  animation: blk-in 0.4s both, pulse 2.4s 3s ease-out infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 var(--accent-soft); }
  40% { box-shadow: 0 0 0 5px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Hosting: the domain resolves and the light comes on */
.preview__sheet[data-layer="hosting"] .blk--dot {
  animation: blk-in 0.4s both, blink 0.9s 0.8s ease-in-out 3;
}

@keyframes blink {
  50% { opacity: 0.15; }
}

.preview__sheet[data-layer="hosting"] .blk--edge {
  animation: blk-in 0.4s both, sweep 1.6s 1s var(--ease-out) both;
}

@keyframes sweep {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

/* Under the scene: step through the layers */
.scene__col {
  display: grid;
  gap: 0.5rem;
}

.scene__nav {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 1.5rem;
}

.scene__step {
  min-width: 9ch;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-align: center;
}

.magnet:disabled {
  color: var(--muted);
  opacity: 0.45;
  cursor: default;
}

.magnet:disabled:hover {
  border-color: transparent;
}

/* The one place a layer is described: what it is here, then, under the
   mono label, what I do for you on it */
.readout__me {
  display: block;
  margin-top: 0.35rem;
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.45;
}

.readout__me span {
  margin-right: 0.35rem;
  color: var(--accent-deep);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
}

.layer {
  cursor: pointer;
}

@media (min-width: 64rem) {
  .exploded {
    grid-template-columns: minmax(0, 1fr) minmax(15rem, 21rem);
    column-gap: clamp(2rem, 5vw, 5rem);
    align-items: center;
  }

  .leaders {
    display: block;
  }

  /* The list is seven names: it sits level with the middle of the stack,
     and the readout keeps its height so nothing below moves as it changes */
  .exploded {
    --scene-h: clamp(26rem, calc(100vh - 16rem), 36rem);
    align-items: start;
  }

  .scene {
    height: var(--scene-h);
  }

  .layers {
    gap: 0.4rem;
    margin-top: max(0px, calc((var(--scene-h) - 23rem) / 2));
  }

  .layer-btn strong {
    font-size: calc((var(--step-1) + var(--step-2)) / 2);
  }

  .anatomy .readout {
    min-height: 6.5em;
  }
}

/* Chips: every .tools list is a row of stickers now (the Toolkit pile and
   the side-project stacks); the li is only a wrapper */
.tools {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tools > li {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.3;
}

.tool {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.study__stack .sticker {
  font-size: 0.85rem;
}

/* ==========================================================================
   Code listings
   ========================================================================== */

/* Code listings: set on the page like a figure in a book. Rules above and
   below, line numbers in the margin, and the caption underneath */
.listing {
  display: flex;
  flex-direction: column;
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
}

.listing pre {
  margin: 0;
  padding: 1.1rem 0 1.25rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--line);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.65;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  counter-reset: line;
}

/* Long lines wrap under their own number rather than scrolling. The column
   drops the newlines between lines, so each line is one block */
.listing pre code {
  display: flex;
  flex-direction: column;
}

.listing .ln {
  padding-left: 2.75rem;
  text-indent: -2.75rem;
}

.listing .ln::before {
  content: counter(line);
  counter-increment: line;
  display: inline-block;
  width: 2.75rem;
  padding-right: 1.25rem;
  color: color-mix(in srgb, var(--text) 35%, transparent);
  font-size: 0.9em;
  text-align: right;
  user-select: none;
}

.listing .c { color: var(--code-cmt); font-style: italic; }
.listing .k { color: var(--code-kw); }
.listing .s { color: var(--code-str); }
.listing .n { color: var(--code-num); }

.listing figcaption {
  order: 1;
  max-width: 64ch;
  margin-top: 0.9rem;
  color: var(--muted);
  font-size: var(--step--1);
  line-height: 1.5;
}

.listing figcaption strong {
  color: var(--text);
  font-weight: 700;
}

/* ==========================================================================
   Hire: the small-business offer
   ========================================================================== */

.hire {
  padding-block: var(--section-space);
}

.hire .section-head h2 {
  max-width: 14ch;
}

.hire__layout {
  display: grid;
  gap: 2.5rem;
}

.hire__side {
  display: grid;
  gap: 1.25rem;
  align-content: start;
}

/* Services: one entry per thing I handle, each under its own rule */
.services {
  display: grid;
  gap: 0 2.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.service {
  display: grid;
  gap: 0.5rem;
  align-content: start;
  padding: 1.5rem 0 1.75rem;
  border-top: 1px solid var(--line);
}

.service__icon {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  margin-bottom: 0.4rem;
  color: var(--brand);
}

.service__icon svg {
  width: 1.5rem;
  height: 1.5rem;
  fill: currentColor;
}

.service__icon--line svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.service h3 {
  font-size: var(--step-1);
  line-height: 1.2;
}

.service p {
  color: var(--muted);
  line-height: 1.5;
}

/* The status report: a ruled ledger in monospace */
.ops {
  margin: 2rem 0 0;
}

.ops__title {
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.78rem;
}

.ops__log {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1.5;
}

.ops__log li {
  display: grid;
  grid-template-columns: 1rem 5rem minmax(0, 1fr);
  column-gap: 0.75rem;
  padding-block: 0.55rem;
  border-bottom: 1px solid var(--line);
}

.ops__ok {
  color: var(--accent);
}

.ops__key {
  color: var(--muted);
}

.ops__caption {
  max-width: 60ch;
  padding-top: 0.9rem;
  color: var(--muted);
  font-size: var(--step--1);
  line-height: 1.5;
}

/* The offer: a heavy rule, the price, and the button */
.offer {
  padding-top: 1.5rem;
  border-top: 2px solid var(--rule);
}

.offer__kicker {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
}

.offer__price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.offer__price strong {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: var(--display-weight);
  line-height: 1;
}

.offer__price span {
  color: var(--muted);
  font-size: var(--step-0);
}

.offer__sub {
  margin-top: 0.9rem;
  line-height: 1.5;
}

.offer__list {
  display: grid;
  gap: 0.6rem;
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
  line-height: 1.45;
}

.offer__list li {
  position: relative;
  padding-left: 1.5rem;
}

.offer__list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 700;
}

.offer__cta {
  margin-top: 1.5rem;
}

.offer__note {
  margin-top: 1rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

/* Fit: who it's for, and who it isn't */
.fit {
  display: grid;
  gap: 2rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}

.fit h3 {
  margin-bottom: 0.8rem;
  font-size: var(--step-1);
}

.fit ul {
  display: grid;
  gap: 0.7rem;
  margin: 0;
  padding: 0;
  list-style: none;
  line-height: 1.5;
}

.fit li {
  position: relative;
  padding-left: 1.5rem;
}

.fit li::before {
  content: "";
  position: absolute;
  top: 0.55em;
  left: 0;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--accent);
}

.fit__col--not li::before {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--muted);
}

.fit__col--not h3,
.fit__col--not li {
  color: var(--muted);
}

@media (min-width: 40rem) {
  .services,
  .fit {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .hire__layout {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
  }

  .hire__side {
    position: sticky;
    top: 5.5rem;
  }
}

/* ==========================================================================
   Off the clock
   ========================================================================== */

.beyond {
  padding-block: var(--section-space);
  background: var(--bg-2);
  color: var(--text);
}

.beyond :focus-visible {
  outline-color: var(--accent);
}

.beyond .section-head h2 {
  font-size: var(--step-4);
}

.beyond a {
  color: var(--text);
  text-decoration-color: var(--accent);
}

/* Photos with captions under them, no card around each. One column on phones;
   on tablets the rental runs full width over two pairs; on desktop the rental
   takes two columns beside Undrly and Disney, then the dogs beside the notes */
.hobbies {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem 1.5rem;
  align-items: start;
}

@media (min-width: 40rem) {
  .hobbies {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .hobby--lead,
  .hobby-notes {
    grid-column: 1 / -1;
  }
}

.hobby {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--text);
  line-height: 1.4;
  text-decoration: none;
}

.hobby > img,
.hobby > .hobby__logo {
  overflow: hidden;
  border-radius: var(--radius-s);
}

.hobby > img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 34rem;
  object-fit: cover;
  object-position: 50% 30%;
  margin-bottom: 0.6rem;
  transition: opacity 0.3s ease;
}

.hobby > span:last-child {
  color: var(--muted);
  font-size: var(--step--1);
}

.hobby__kicker {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.hobby > strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: var(--display-weight);
  line-height: 1.15;
}

a.hobby:hover > strong {
  color: var(--accent);
}

a.hobby:hover > img {
  opacity: 0.9;
}

/* Undrly: the wordmark sits where the other cards have a photo */
.hobby > .hobby__logo {
  display: grid;
  place-items: center;
  padding: 2.5rem 1.5rem;
  margin-bottom: 0.6rem;
  background: var(--surface-2);
}

.hobby__logo img {
  display: block;
  width: min(100%, 13rem);
  height: auto;
}

a.hobby:hover .hobby__logo {
  background: var(--accent-soft);
}

/* The ones with no photo: ruled notes, the last block of the grid */
.hobby-notes {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 40rem) {
  .hobby-notes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.hobby--text {
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

@media (min-width: 56rem) {
  .hobbies {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "lead lead undrly"
      "lead lead disney"
      "dixie tilly notes";
    gap: 2.5rem 2rem;
  }

  .hobby--lead { grid-area: lead; }
  .hobby--undrly { grid-area: undrly; }
  .hobby--disney { grid-area: disney; }
  .hobby--dixie { grid-area: dixie; }
  .hobby--tilly { grid-area: tilly; }

  .hobby-notes {
    grid-area: notes;
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact {
  position: relative;
  padding-block: clamp(3.5rem, 8vw, 6rem);
  border-top: 1px solid var(--line);
  background: var(--bg);
  color: var(--text);
}

.contact__inner {
  display: grid;
  gap: 2.5rem;
  align-items: start;
}

.contact h2 {
  font-size: var(--step-4);
}

.contact__copy p {
  margin-top: 1rem;
  font-size: var(--step-1);
}

.contact__copy a {
  color: var(--accent);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.contact :focus-visible {
  outline-color: var(--accent);
}

/* The form: ruled rows under a heavy rule, no card */
.booking {
  display: grid;
  gap: 0;
  border-top: 2px solid var(--rule);
}

.booking__field {
  display: grid;
  gap: 0.15rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
}

.booking__field label,
.booking__label {
  font-size: var(--step--1);
  font-weight: 700;
}

.booking select,
.booking input,
.booking textarea {
  width: 100%;
  padding: 0.25rem 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  line-height: 1.4;
}

.booking select {
  cursor: pointer;
}

.booking textarea {
  resize: vertical;
}

.booking input::placeholder,
.booking textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}

.booking :is(input, select, textarea):focus-visible {
  outline-offset: 4px;
}

.booking__value {
  padding: 0.25rem 0;
}

.booking__submit {
  justify-self: start;
  margin-top: 1.5rem;
}

.booking__note {
  margin-top: 0.9rem;
  color: var(--muted);
  font-size: var(--step--1);
}

@media (min-width: 56rem) {
  .contact__inner {
    grid-template-columns: minmax(0, 1.2fr) minmax(18rem, 0.8fr);
    column-gap: clamp(3rem, 6vw, 6rem);
  }

  .booking__field {
    grid-template-columns: 8.5rem 1fr;
    align-items: start;
  }

  .booking__field label {
    padding-top: 0.3rem;
  }
}

/* ==========================================================================
   Back to top
   ========================================================================== */

.to-top {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 40;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 12px 28px -12px rgba(11, 124, 97, 0.6);
  cursor: pointer;
  opacity: 0;
  translate: 0 1rem;
  pointer-events: none;
  transition: opacity 0.3s ease, translate 0.4s var(--ease-out), background-color 0.2s ease;
}

.to-top[hidden] {
  display: grid;
}

.to-top.is-visible {
  opacity: 1;
  translate: 0 0;
  pointer-events: auto;
}

.to-top:hover {
  background: var(--accent-deep);
}

.to-top:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 3px;
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

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

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    animation-duration: 0.01ms !important;
  }

  /* No pulsing for people who turn motion off */
  .job__marker,
  .flow__steps li::before,
  .toolbox .toolbox__chips > li:has(.tool) .sticker::after {
    animation: none !important;
  }
}
