@font-face {
  font-family: "Iowan Old Style Local";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Iowan Old Style"), local("IowanOldStyle-Roman"), local("Iowan Old Style BT");
}
@font-face {
  font-family: "Iowan Old Style Local";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Iowan Old Style Bold"), local("IowanOldStyle-Bold");
}

:root {
  --font-reading: "Iowan Old Style Local", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-ui: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --bg: #fff;
  --text-copy: #282828;
  --text-heading: #282828;
  --text-secondary: #504945;
  --text-nav: #676767;
  --line-subtle: color-mix(in srgb, var(--text-copy) 10%, transparent);
  --surface-subtle: #f3f3f2;
  --focus-color: #6657c8;
}

/* Dark: the system setting, unless theme.js has set data-theme from the toggle. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1b1a19;
    --text-copy: #e8e5df;
    --text-heading: #f4f1eb;
    --text-secondary: #cbc6be;
    --text-nav: #aaa59e;
    --surface-subtle: #242321;
    --line-subtle: color-mix(in srgb, var(--text-copy) 18%, transparent);
  }
}
:root[data-theme="dark"] {
  --bg: #1b1a19;
  --text-copy: #e8e5df;
  --text-heading: #f4f1eb;
  --text-secondary: #cbc6be;
  --text-nav: #aaa59e;
  --surface-subtle: #242321;
  --line-subtle: color-mix(in srgb, var(--text-copy) 18%, transparent);
  color-scheme: dark;
}
:root[data-theme="light"] {
  color-scheme: light;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Desktop renders at 90%. Viewport lengths are divided by --zoom to compensate. */
:root {
  --zoom: 1;
}
@media (min-width: 1100px) {
  :root {
    --zoom: 0.9;
  }
  html {
    zoom: var(--zoom);
  }
  body,
  .site-shell {
    min-height: calc(100vh / var(--zoom));
  }
}

html {
  background: var(--bg);
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: gray transparent;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg);
  min-height: 100vh;
  color: var(--text-copy);
  font-family: var(--font-reading);
  font-size: 19px;
  line-height: 1.6;
  margin: 0;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

:focus-visible {
  outline: 2px solid var(--focus-color);
  outline-offset: 2px;
}

.site-shell {
  --page-pad: clamp(1.25rem, 3.4vw, 3.25rem);
  min-height: 100vh;
  padding: var(--page-pad);
}

.content-frame {
  --content-width: 600px;
  width: min(100%, var(--content-width));
  overflow-wrap: break-word;
  margin-inline: auto;
}

.content-frame p {
  text-wrap: pretty;
  margin: 0 0 1.45rem;
}

.site-title {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  text-wrap: balance;
  font-weight: 600;
  margin: 0 0 0.95em;
  font-size: clamp(2.325rem, 3.5vw, 2.775rem);
  line-height: 1.15;
}

.content-frame a.site-title-link {
  color: inherit;
  text-decoration: none;
  transition: opacity 0.2s;
}
.content-frame a.site-title-link:hover {
  color: inherit;
  opacity: 0.72;
}

.site-title-at {
  margin-right: 0.015em;
  font-size: 1.1em;
  line-height: 0;
  display: inline-block;
  position: relative;
  top: 0.015em;
}

.content-frame a {
  color: var(--text-nav);
  text-decoration-line: underline;
  text-decoration-color: color-mix(in srgb, var(--text-nav) 30%, transparent);
  text-decoration-skip-ink: auto;
  text-underline-offset: 0.18em;
  transition: color 0.3s ease-in-out, text-decoration-color 0.3s ease-in-out;
}
.content-frame a:hover {
  color: var(--text-secondary);
  text-decoration-color: color-mix(in srgb, var(--text-secondary) 30%, transparent);
}

.bio-section {
  margin-bottom: 3.25rem;
}

.bio-toggle {
  border-bottom: 1px solid var(--line-subtle);
  color: var(--text-nav);
  font-family: var(--font-ui);
  letter-spacing: 0.01em;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 1.35rem;
  padding-bottom: 0.55rem;
  font-size: 16px;
  line-height: 1.4;
  display: flex;
}

.bio-toggle-options {
  gap: 1rem;
  margin-left: auto;
  display: flex;
}

.bio-toggle button {
  color: inherit;
  cursor: pointer;
  font: inherit;
  background: none;
  border: 0;
  padding: 0.2rem 0;
  transition: color 0.16s;
  position: relative;
}
.bio-toggle button:hover,
.bio-toggle button[aria-pressed="true"] {
  color: var(--text-copy);
}
.bio-toggle button[aria-pressed="true"]::after {
  background: var(--text-copy);
  content: "";
  height: 1px;
  position: absolute;
  bottom: -0.62rem;
  left: 0;
  right: 0;
}

.writing-index,
.writing-index > section + section {
  margin-top: 3.5rem;
}

.writing-index h2 {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 1.2rem;
  font-size: 1.575rem;
  font-weight: 600;
  line-height: 1.4;
}

.notes-list {
  columns: 2;
  column-gap: 2.5rem;
  margin: 0.8em 0 0;
  padding-left: 1.1em;
  list-style: square;
}
.notes-list li {
  break-inside: avoid;
  margin-bottom: 0.2rem;
  padding: 0 0 0 0.15em;
}
.notes-list > li::marker {
  color: color-mix(in srgb, var(--text-nav) 70%, transparent);
}

.blogs-list {
  border-top: 1px solid var(--line-subtle);
  margin-top: 0.85em;
}

.content-frame .blog-row {
  border-bottom: 1px solid var(--line-subtle);
  color: var(--text-copy);
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1.25rem;
  padding: 0.72em 0;
  text-decoration: none;
  display: grid;
}
.content-frame .blog-row:hover {
  color: var(--text-copy);
}

.blog-row time,
.blog-row .blog-meta {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-variant-numeric: lining-nums tabular-nums;
  white-space: nowrap;
  font-size: 16px;
}

@media (hover: hover) and (pointer: fine) {
  .content-frame .blog-row {
    transition: opacity 0.3s ease-in-out;
  }
  .blogs-list:hover .blog-row {
    opacity: 0.8;
  }
  .blogs-list:hover .blog-row:hover {
    opacity: 1;
  }
}

@media (max-width: 639px) {
  .site-shell {
    padding: 2.5rem 1.25rem 1.25rem;
  }
  .notes-list {
    columns: 1;
  }
  .content-frame .blog-row {
    grid-template-columns: 1fr;
    gap: 0.15rem;
  }
  .blog-row time,
  .blog-row .blog-meta {
    font-size: 15px;
  }
}

.content-frame a.tabs-back-link {
  color: var(--text-nav);
  font-family: var(--font-ui);
  margin-bottom: 0.75rem;
  font-size: 15px;
  text-decoration: none;
  display: inline-block;
}
.content-frame a.tabs-back-link:hover {
  color: var(--text-secondary);
}

.content-title {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  text-wrap: balance;
  font-weight: 600;
  margin: 0 0 0.95em;
  font-size: clamp(2.325rem, 3.5vw, 2.775rem);
  line-height: 1.15;
}

.content-heading {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 3.1rem 0 0.35rem;
  font-size: 1.575rem;
  font-weight: 600;
  line-height: 1.4;
}
.content-frame .content-heading a {
  color: inherit;
}

.content-frame .note-meta {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 16px;
  margin-bottom: 0.9rem;
}

.content-list {
  margin: 0 0 1.45rem;
  padding-left: 1.1em;
  list-style: square;
}
.content-frame .content-list li {
  text-wrap: pretty;
  margin: 0 0 0.2rem;
  padding: 0 0 0 0.15em;
}
.content-list > li::marker {
  color: color-mix(in srgb, var(--text-nav) 70%, transparent);
}

.blog-empty {
  border-bottom: 1px solid var(--line-subtle);
  color: var(--text-nav);
  padding: 0.72em 0;
}

.shot {
  margin: 0 0 1.45rem;
}
.shot img {
  border: 1px solid var(--line-subtle);
  border-radius: 10px;
  width: 100%;
  height: auto;
  display: block;
}

.home-visual {
  display: none;
}

@media (min-width: 1100px) {
  .content-frame.home-frame {
    width: min(100%, 1120px);
  }
  .home-layout {
    grid-template-columns: minmax(0, 600px) minmax(340px, 1fr);
    align-items: start;
    gap: clamp(4rem, 8.5vw, 7.5rem);
    display: grid;
  }
  .home-visual {
    border: 1px solid var(--line-subtle);
    background: var(--surface-subtle);
    border-radius: 10px;
    top: var(--page-pad);
    height: calc(100svh - (2 * var(--page-pad)));
    min-height: 420px;
    max-height: 760px;
    flex-direction: column;
    display: flex;
    position: sticky;
    overflow: hidden;
  }
  .home-visual canvas {
    flex: 1;
    width: 100%;
    min-height: 0;
    display: block;
  }
  .content-frame .home-visual-caption {
    border-top: 1px solid var(--line-subtle);
    color: var(--text-nav);
    font-family: var(--font-ui);
    font-variant-numeric: tabular-nums;
    justify-content: space-between;
    gap: 1rem;
    margin: 0;
    padding: 0.7rem 0.9rem;
    font-size: 15px;
    line-height: 1.4;
    display: flex;
  }
  .home-visual-caption span:last-child {
    white-space: nowrap;
  }
}

.page-media {
  margin-top: 2.5rem;
}

.content-frame .shot figcaption {
  color: var(--text-nav);
  font-family: var(--font-ui);
  margin-top: 0.6rem;
  font-size: 15px;
  line-height: 1.5;
}

.shot + .shot {
  margin-top: 2rem;
}

.embed {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  border-radius: 10px;
  aspect-ratio: 16 / 10;
  position: relative;
  overflow: hidden;
}
.embed iframe {
  transform-origin: 0 0;
  border: 0;
  width: 1440px;
  height: 900px;
  position: absolute;
  top: 0;
  left: 0;
}

@media (min-width: 1100px) {
  .content-frame.page-frame {
    width: min(100% - 114px, 1400px);
  }
  .content-frame.page-frame:has(.notes-panel) {
    width: min(100%, 1180px);
  }
  .page-layout {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(3.5rem, 7.5vw, 7.5rem);
    display: grid;
  }
  .page-media {
    margin-top: 0;
    padding-top: 2.4rem;
  }
}

/* Motion */
@view-transition {
  navigation: auto;
}
::view-transition-old(root) {
  animation: 0.16s ease-in both page-out;
}
::view-transition-new(root) {
  animation: 0.28s ease-out 0.08s both page-in;
}
@keyframes page-out {
  to {
    opacity: 0;
  }
}
@keyframes page-in {
  from {
    opacity: 0;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

.home-copy > *,
.writing-index > section,
.page-copy > *,
.page-media > *,
.content-frame:not(.home-frame):not(.page-frame) > * {
  animation: 1s cubic-bezier(0.22, 1, 0.36, 1) both rise;
  animation-delay: calc(var(--i, 0) * 70ms);
}
.home-visual {
  animation: 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s both rise;
}

#bio-content {
  overflow: hidden;
}
[data-bio-panel].is-entering {
  animation: 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) both rise;
}

.bio-toggle button::after {
  background: var(--text-copy);
  content: "";
  height: 1px;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  position: absolute;
  bottom: -0.62rem;
  left: 0;
  right: 0;
  transform: scaleX(0);
}
.bio-toggle button[aria-pressed="true"]::after {
  transform: scaleX(1);
}

.notes-list a,
.content-list a,
.tabs-back-link {
  transition: color 0.3s ease-in-out, text-decoration-color 0.3s ease-in-out, transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  display: inline-block;
}
@media (hover: hover) and (pointer: fine) {
  .notes-list a:hover,
  .content-list a:hover {
    transform: translateX(3px);
  }
  .content-frame a.tabs-back-link:hover {
    transform: translateX(-3px);
  }
  .shot img,
  .embed {
    transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .shot img:hover,
  .embed:hover {
    transform: translateY(-3px);
    box-shadow: 0 18px 40px -24px color-mix(in srgb, var(--text-copy) 45%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Timeline */

.timeline {
  margin: 3rem 0 0;
  padding: 0;
  list-style: none;
  position: relative;
}
.timeline::before {
  background: linear-gradient(to bottom, var(--line-subtle), var(--text-nav));
  content: "";
  width: 1px;
  position: absolute;
  top: 0.7rem;
  bottom: 0.7rem;
  left: 5px;
  transform-origin: top;
  animation: 1.4s cubic-bezier(0.2, 0.7, 0.2, 1) 0.2s both draw-line;
}
@keyframes draw-line {
  from {
    transform: scaleY(0);
  }
}

.timeline-step {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 2rem;
  padding: 0 0 2.75rem 2.25rem;
  display: grid;
  position: relative;
  animation: 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both rise;
  animation-delay: calc(0.25s + var(--i, 0) * 0.14s);
}
.timeline-step:last-child {
  padding-bottom: 0;
}
.timeline-step::before {
  background: var(--bg);
  border: 1px solid var(--text-nav);
  border-radius: 50%;
  content: "";
  width: 11px;
  height: 11px;
  position: absolute;
  top: 0.45rem;
  left: 0;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), background-color 0.3s;
}
.timeline-step:hover::before {
  background: var(--text-nav);
  transform: scale(1.3);
}
.timeline-step.is-current::before {
  background: var(--text-heading);
  border-color: var(--text-heading);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--text-heading) 14%, transparent);
  animation: 2.4s ease-in-out infinite pulse;
}
@keyframes pulse {
  50% {
    box-shadow: 0 0 0 10px color-mix(in srgb, var(--text-heading) 0%, transparent);
  }
}

.content-frame .timeline-when {
  color: var(--text-nav);
  font-family: var(--font-ui);
  letter-spacing: 0.01em;
  margin: 0 0 0.2rem;
  font-size: 15px;
}
.timeline-title {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  margin: 0;
  font-size: 1.575rem;
  font-weight: 600;
  line-height: 1.3;
}
.content-frame .timeline-role {
  color: var(--text-secondary);
  margin: 0.15rem 0 0.6rem;
  font-style: italic;
}
.content-frame .timeline-body p:last-child {
  margin-bottom: 0;
}

.content-frame .timeline-stat {
  text-align: right;
  flex-direction: column;
  min-width: 8.5rem;
  margin: 0;
  padding-top: 1.35rem;
  display: flex;
}
.timeline-stat strong {
  color: var(--text-heading);
  font-variant-numeric: lining-nums;
  letter-spacing: -0.03em;
  font-size: 2.6rem;
  font-weight: 600;
  line-height: 1.05;
}
.timeline-stat span {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.35;
}
.timeline-stat span + strong {
  margin-top: 0.8rem;
}

@media (max-width: 639px) {
  .timeline-step {
    grid-template-columns: 1fr;
    gap: 0.9rem;
  }
  .content-frame .timeline-stat {
    text-align: left;
    padding-top: 0;
  }
}

/* Side cards: right-column content for pages without screenshots */
.side-card {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  border-radius: 10px;
  padding: 1.4rem 1.6rem;
}
.content-frame .side-card-label {
  color: var(--text-nav);
  font-family: var(--font-ui);
  letter-spacing: 0.01em;
  margin: 0 0 0.8rem;
  font-size: 15px;
}
.side-card-list {
  margin: 0;
  padding-left: 1.5em;
  font-size: 17px;
  line-height: 1.45;
}
.side-card-list li {
  margin-bottom: 0.55rem;
}
.side-card-list li::marker {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 14px;
}
.content-frame .side-card-list a {
  color: var(--text-copy);
  text-decoration-color: transparent;
}
.content-frame .side-card-list a:hover {
  text-decoration-color: color-mix(in srgb, var(--text-copy) 30%, transparent);
}
.content-frame .side-stat {
  flex-direction: column;
  margin: 0;
  display: flex;
}
.side-stat + .side-stat {
  border-top: 1px solid var(--line-subtle);
  margin-top: 1.3rem;
  padding-top: 1.3rem;
}
.side-stat strong {
  color: var(--text-heading);
  letter-spacing: -0.03em;
  font-size: 3.4rem;
  font-weight: 600;
  line-height: 1.05;
}
.side-stat span {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 15px;
}
html {
  scroll-behavior: smooth;
}
.content-heading {
  scroll-margin-top: 2rem;
}

@media (min-width: 1100px) {
  .page-media.is-sticky {
    top: var(--page-pad);
    position: sticky;
  }
  .timeline-frame > a,
  .timeline-frame > h1,
  .timeline-frame > p {
    max-width: 520px;
  }
  .timeline-frame > a {
    display: block;
    width: fit-content;
  }
  .timeline-step {
    grid-template-columns: minmax(0, calc(520px - 2.25rem)) minmax(0, 1fr);
    gap: clamp(4rem, 8.5vw, 7.5rem);
  }
  .content-frame .timeline-stat {
    text-align: left;
    padding-top: 0.9rem;
  }
  .timeline-stat strong {
    font-size: 3.4rem;
  }
}

/* Notes browser */
.paper-list {
  border-top: 1px solid var(--line-subtle);
  margin: 2.2rem 0 0;
  padding: 0;
  list-style: none;
}
.paper {
  border-bottom: 1px solid var(--line-subtle);
}
.paper-toggle {
  color: var(--text-copy);
  cursor: pointer;
  font: inherit;
  text-align: left;
  background: none;
  border: 0;
  flex-direction: column;
  gap: 0.1rem;
  width: 100%;
  padding: 0.8em 1.6rem 0.8em 0;
  transition: opacity 0.3s ease-in-out, padding-left 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  display: flex;
  position: relative;
}
.paper-toggle::after {
  color: var(--text-nav);
  content: "+";
  font-family: var(--font-ui);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  position: absolute;
  top: 0.8em;
  right: 0.2rem;
}
.paper-toggle[aria-expanded="true"]::after {
  transform: rotate(45deg);
}
.paper-toggle[aria-expanded="true"] {
  padding-left: 0.6rem;
}
.paper-toggle[aria-expanded="true"] .paper-title {
  color: var(--text-heading);
  font-weight: 600;
}
.paper-meta {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 15px;
}
@media (hover: hover) and (pointer: fine) {
  .paper-list:hover .paper-toggle {
    opacity: 0.7;
  }
  .paper-list:hover .paper-toggle:hover,
  .paper-list:hover .paper-toggle[aria-expanded="true"] {
    opacity: 1;
  }
}
.paper-notes {
  overflow: hidden;
  padding-bottom: 0.6rem;
}
.content-frame .paper-source {
  font-family: var(--font-ui);
  margin-bottom: 0.9rem;
  font-size: 15px;
}
.paper-notes h3,
.notes-panel h3 {
  color: var(--text-nav);
  font-family: var(--font-ui);
  letter-spacing: 0.01em;
  margin: 1.3rem 0 0.45rem;
  font-size: 15px;
  font-weight: 500;
}
.notes-panel-title {
  color: var(--text-heading);
  letter-spacing: -0.02em;
  margin: 0 0 0.5rem;
  font-size: 1.575rem;
  font-weight: 600;
  line-height: 1.3;
}
.notes-panel {
  display: none;
}

@media (min-width: 1100px) {
  .notes-panel {
    max-height: calc(100svh - (2 * var(--page-pad)));
    display: block;
    overflow-y: auto;
    scrollbar-width: thin;
  }
  .notes-panel .content-list:last-child {
    margin-bottom: 0;
  }
  .paper-list .paper-notes {
    display: none;
  }
}

/* Amphi mascot */
.creature-scene {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  border-radius: 10px;
  flex-direction: column;
  align-items: center;
  padding: 2.2rem 1.5rem 2.4rem;
  display: flex;
}
.content-frame .creature-bubble {
  background: var(--text-heading);
  color: var(--bg);
  font-family: var(--font-ui);
  text-align: center;
  border-radius: 12px;
  min-width: 12rem;
  max-width: 100%;
  margin: 0 0 1.6rem;
  padding: 0.7rem 1.1rem;
  font-size: 17px;
  line-height: 1.35;
  position: relative;
}
.creature-bubble span {
  display: inline-block;
}
.creature-bubble::after {
  background: var(--text-heading);
  content: "";
  width: 14px;
  height: 14px;
  position: absolute;
  bottom: -6px;
  left: calc(50% - 7px);
  transform: rotate(45deg);
  border-radius: 2px;
}
.creature {
  cursor: pointer;
  background: none;
  border: 0;
  width: min(62%, 280px);
  padding: 0;
  position: relative;
  rotate: var(--lean, 0deg);
  transition: rotate 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
  animation: 3.6s ease-in-out infinite creature-float;
}
.creature img {
  width: 100%;
  height: auto;
  display: block;
  user-select: none;
}
.creature-pupil {
  background: var(--text-heading);
  border-radius: 22%;
  width: 6%;
  height: 6%;
  margin: -3% 0 0 -3%;
  position: absolute;
  top: 68.8%;
  transition: transform 0.18s ease-out;
}
.creature-shadow {
  background: radial-gradient(closest-side, color-mix(in srgb, var(--text-copy) 22%, transparent), transparent);
  width: min(48%, 220px);
  height: 14px;
  margin-top: 1.1rem;
  animation: 3.6s ease-in-out infinite creature-shadow;
}
@keyframes creature-float {
  50% {
    translate: 0 -10px;
  }
}
@keyframes creature-shadow {
  50% {
    opacity: 0.55;
    scale: 0.86 1;
  }
}
.creature-stage .creature img:hover {
  box-shadow: none;
  transform: none;
}

/* Roblox page: knockback toy */
.timeline-side {
  min-width: 0;
}
.knockback {
  margin: 1.4rem 0 0;
}
.knockback {
  z-index: 5;
  position: relative;
}
.knockback-pad {
  cursor: crosshair;
  touch-action: manipulation;
  height: 230px;
  position: relative;
}
/* No box: the canvas reaches far above the pad and draws over the text, so the block can keep flying up. */
.knockback canvas {
  pointer-events: none;
  width: 100%;
  height: calc(100% + 75vh);
  position: absolute;
  bottom: 0;
  left: 0;
}
.content-frame .knockback figcaption {
  font-variant-numeric: tabular-nums;
  justify-content: space-between;
  gap: 1rem;
  display: flex;
}
.knockback figcaption span:last-child {
  color: var(--text-copy);
  white-space: nowrap;
}
@media (max-width: 1099px) {
  .timeline-step:has(.timeline-side) {
    grid-template-columns: 1fr;
    gap: 0.9rem;
  }
  .timeline-side .timeline-stat {
    text-align: left;
    padding-top: 0;
  }
}

/* TSA page: 3D ring logo */
.logo-stage canvas {
  border: 1px solid var(--line-subtle);
  background: radial-gradient(60% 80% at 22% 50%, #1b3fae55, transparent 70%), radial-gradient(55% 80% at 82% 45%, #c0263f55, transparent 70%), #05040f;
  cursor: grab;
  touch-action: none;
  border-radius: 10px;
  aspect-ratio: 16 / 10;
  width: 100%;
  display: block;
}
.logo-stage canvas:active {
  cursor: grabbing;
}
.logo-stage canvas {
  filter: drop-shadow(0 0 0 transparent);
}

/* Screenshot carousel and lightbox */
.gallery-track {
  margin: 0;
  padding: 0;
  list-style: none;
}
.gallery-zoom {
  cursor: zoom-in;
  background: none;
  border: 0;
  width: 100%;
  padding: 0;
  display: block;
}
.content-frame .gallery-caption {
  color: var(--text-nav);
  font-family: var(--font-ui);
  min-height: 6.2em;
  margin: 0.6rem 0 0;
  font-size: 15px;
  line-height: 1.5;
}
.gallery-nav {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  align-items: center;
  gap: 0.9rem;
  margin-top: 0.4rem;
  font-size: 15px;
  display: flex;
}
.gallery-nav button,
.lightbox button {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  color: var(--text-copy);
  cursor: pointer;
  font: inherit;
  border-radius: 999px;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  line-height: 1;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), background-color 0.2s, color 0.2s;
  display: grid;
}
.gallery-nav button:hover,
.lightbox button:hover {
  background: var(--text-heading);
  color: var(--bg);
}
.gallery-prev:hover,
.lightbox-prev:hover {
  transform: translateX(-2px);
}
.gallery-next:hover,
.lightbox-next:hover {
  transform: translateX(2px);
}

.lightbox {
  background: none;
  border: 0;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: clamp(1rem, 3vw, 2.5rem);
}
.lightbox[open] {
  display: grid;
}
.lightbox::backdrop {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
}
.lightbox figure {
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  min-height: 0;
  max-height: 100%;
  margin: 0;
  display: flex;
}
.lightbox img {
  border: 1px solid var(--line-subtle);
  cursor: zoom-out;
  object-fit: contain;
  border-radius: 10px;
  max-width: 100%;
  min-height: 0;
  max-height: calc(100dvh - 10rem);
  box-shadow: 0 30px 80px -30px #000;
}
.lightbox figcaption {
  color: var(--text-secondary);
  font-family: var(--font-ui);
  text-align: center;
  max-width: 70ch;
  font-size: 15px;
  line-height: 1.5;
}
.lightbox-close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
}

/* Mascot and logo sit directly on the page: no frame, just a floor shadow */
.creature-scene {
  background: none;
  border: 0;
  padding: 0.5rem 0 1rem;
}
.logo-stage {
  flex-direction: column;
  align-items: center;
  display: flex;
}
.logo-stage canvas {
  background: none;
  border: 0;
  border-radius: 0;
  aspect-ratio: 1;
  width: min(100%, 460px);
}
.logo-shadow {
  background: radial-gradient(closest-side, color-mix(in srgb, #000 55%, transparent), transparent);
  width: min(60%, 300px);
  height: 22px;
  margin-top: -1.2rem;
}
.content-frame .logo-stage figcaption {
  align-self: stretch;
  text-align: center;
}
.content-frame .creature-stage figcaption {
  text-align: center;
}
.creature-stage .creature img {
  border: 0;
  border-radius: 0;
}

/* Social link card */
.content-frame a.social-card {
  border: 1px solid var(--line-subtle);
  color: var(--text-copy);
  text-decoration: none;
  border-radius: 14px;
  align-items: center;
  gap: 1rem;
  margin: 1.5rem 0;
  padding: 0.85rem 1.1rem 0.85rem 0.85rem;
  transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1), border-color 0.3s, background-color 0.3s;
  display: flex;
}
.content-frame a.social-card:hover {
  background: var(--surface-subtle);
  border-color: var(--text-nav);
  color: var(--text-copy);
  transform: translateY(-2px);
}
.social-avatar {
  border-radius: 50%;
  flex: none;
  width: 64px;
  height: 64px;
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.social-card:hover .social-avatar {
  transform: rotate(-6deg) scale(1.06);
}
.social-text {
  flex-direction: column;
  flex: 1;
  min-width: 0;
  line-height: 1.3;
  display: flex;
}
.social-text strong {
  color: var(--text-heading);
  font-weight: 600;
}
.social-text span {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 15px;
}
.social-arrow {
  color: var(--text-nav);
  font-family: var(--font-ui);
  transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.social-card:hover .social-arrow {
  transform: translate(3px, -3px);
}

/* Circle packing on the research page */
.packing-card canvas {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  border-radius: 10px;
  aspect-ratio: 5 / 4;
  width: 100%;
  display: block;
}
.content-frame .packing-card figcaption {
  font-variant-numeric: tabular-nums;
  justify-content: space-between;
  gap: 1rem;
  display: flex;
}
.packing-card figcaption span:last-child {
  white-space: nowrap;
}

/* Packing caption: fixed two-line layout so the counter never changes the canvas height */
@media (min-width: 1100px) {
  .content-frame .home-visual-caption {
    flex-direction: column;
    gap: 0.15rem;
  }
}
.content-frame .packing-card figcaption {
  flex-direction: column;
  gap: 0.15rem;
}

/* Open Literacy: wordmark, characters, bare counters */
@font-face {
  font-family: "Reddit Sans";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/reddit-sans.woff2") format("woff2");
}
.ol-hero {
  margin-bottom: 2.8rem;
}
.ol-characters {
  gap: 1.4rem;
  margin: 0 0 0.6rem 0.2rem;
  display: flex;
}
.ol-character {
  color: var(--text-nav);
  cursor: pointer;
  font-family: var(--font-ui);
  background: none;
  border: 0;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  font-size: 15px;
  display: flex;
}
.ol-character img {
  width: clamp(72px, 8vw, 104px);
  height: auto;
  animation: 3.4s ease-in-out var(--delay) infinite ol-bob;
  display: block;
}
.ol-character:nth-child(2) img {
  animation-name: ol-bob-alt;
}
.content-frame .ol-character img,
.content-frame .ol-character img:hover {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
@keyframes ol-bob {
  50% {
    translate: 0 -9px;
    rotate: -5deg;
  }
}
@keyframes ol-bob-alt {
  50% {
    translate: 0 -7px;
    rotate: 6deg;
  }
}
.content-frame .ol-wordmark {
  color: var(--text-heading);
  font-family: "Reddit Sans", var(--font-ui);
  letter-spacing: -0.055em;
  margin: 0;
  font-size: clamp(3.4rem, 7.2vw, 6.4rem);
  font-weight: 500;
  line-height: 0.92;
}
.ol-wordmark span {
  animation: 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both ol-rise;
  display: inline-block;
}
.ol-wordmark span:last-child {
  animation-delay: 0.12s;
}
@keyframes ol-rise {
  from {
    opacity: 0;
    transform: translateY(0.45em);
  }
}
.content-frame .ol-tagline {
  color: var(--text-secondary);
  font-family: "Reddit Sans", var(--font-ui);
  margin: 1.9rem 0 0;
  font-size: 1.25rem;
}
.ol-tagline em {
  color: #3fa56b;
}

.counters {
  margin: 0;
}
.counter {
  padding: 1.1rem 0 1.2rem;
  position: relative;
}
.counter::before {
  background: var(--line-subtle);
  content: "";
  height: 1px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.2s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.counter.is-in::before {
  transform: scaleX(1);
}
.counter dt {
  color: var(--text-heading);
  font-family: "Gloock", "DM Serif Display", Didot, "Bodoni MT", serif;
  font-style: italic;
  letter-spacing: -0.01em;
  font-size: clamp(2.6rem, 4.2vw, 3.6rem);
  font-weight: 400;
  line-height: 1;
}
.counter dd {
  color: var(--text-nav);
  font-family: var(--font-ui);
  margin: 0.3rem 0 0;
  font-size: 15px;
}

/* Packing panels: a dark stage with a faint colour wash so the circles glow */
.home-visual,
.packing-card canvas {
  background:
    radial-gradient(70% 50% at 20% 12%, #6ea8ff1f, transparent 70%),
    radial-gradient(60% 45% at 85% 88%, #ff8fd01a, transparent 70%),
    radial-gradient(50% 40% at 70% 35%, #3fbf9a14, transparent 70%),
    #121116;
}
@media (prefers-color-scheme: light) {
  .home-visual,
  .packing-card canvas {
    background:
      radial-gradient(70% 50% at 20% 12%, #6ea8ff2e, transparent 70%),
      radial-gradient(60% 45% at 85% 88%, #ff8fd029, transparent 70%),
      radial-gradient(50% 40% at 70% 35%, #3fbf9a24, transparent 70%),
      #f6f5f2;
  }
}

/* Techy panels: grid paper, monospace, one accent */
:root {
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --accent: #3fbf9a;
}
.home-visual,
.packing-card canvas {
  background:
    linear-gradient(color-mix(in srgb, var(--text-copy) 5%, transparent) 1px, transparent 1px) 0 0 / 32px 32px,
    linear-gradient(90deg, color-mix(in srgb, var(--text-copy) 5%, transparent) 1px, transparent 1px) 0 0 / 32px 32px,
    var(--surface-subtle);
}
.packing-card canvas {
  background: var(--surface-subtle);
  border-radius: 10px 10px 0 0;
}
.packing-log {
  border: 1px solid var(--line-subtle);
  background: var(--surface-subtle);
  color: var(--text-nav);
  font-family: var(--font-mono);
  border-top: 0;
  border-radius: 0 0 10px 10px;
  height: calc(6 * 1.6em + 1.5rem);
  margin: 0;
  padding: 0.75rem 0.9rem;
  font-size: 12px;
  line-height: 1.6;
  overflow: hidden;
}
#packing-stat {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 12px;
}

.mascot-field {
  flex: 1;
  min-height: 0;
  position: relative;
  overflow: hidden;
}
.mascot-code {
  color: var(--text-nav);
  font-family: var(--font-mono);
  margin: 0;
  padding: 1.4rem 1.2rem;
  font-size: 12.5px;
  line-height: 1.75;
  position: absolute;
  inset: 0;
  opacity: 0.8;
  pointer-events: none;
  user-select: none;
}
.mascot-code i {
  font-style: normal;
  opacity: 0.4;
}
.mascot-code b {
  color: var(--accent);
  font-weight: 500;
}
.mascot-code u {
  text-decoration: none;
  opacity: 0.55;
}
.mascot-code s {
  color: var(--text-copy);
  text-decoration: none;
}
.mascot {
  cursor: grab;
  touch-action: none;
  width: var(--size);
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
}
.mascot:active {
  cursor: grabbing;
}
.mascot img {
  filter: drop-shadow(0 14px 18px rgb(0 0 0 / 0.35));
  width: 100%;
  height: auto;
  transition: scale 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  display: block;
  pointer-events: none;
}
.mascot:hover img {
  scale: 1.06;
}

/* Home panel: human hand and evolving machine hand, on warm paper */
@media (min-width: 1100px) {
  .home-visual.hands-panel {
    background: #efe9dd;
    border-color: #d9d1c1;
    color: #23201c;
  }
  .hands-panel canvas {
    cursor: pointer;
  }
  .content-frame .hands-title {
    color: #23201c;
    letter-spacing: -0.02em;
    margin: 0;
    padding: 1.3rem 1.3rem 0;
    font-size: 1.45rem;
    font-weight: 600;
    line-height: 1.25;
  }
  .content-frame .hands-panel .home-visual-caption {
    border-top-color: #d9d1c1;
    color: #5d564c;
  }
  #hands-stat {
    color: #c8643c;
    font-family: var(--font-mono);
    font-size: 12px;
  }
}

/* Landing: one mascot beside the text, techy packing readout on the right */
.home-copy {
  position: relative;
}
.home-mascot {
  width: 56px;
  margin-bottom: 1.1rem;
  animation: 3.6s ease-in-out infinite creature-float;
  display: block;
}
.home-mascot img {
  filter: drop-shadow(0 10px 14px rgb(0 0 0 / 0.3));
  width: 100%;
  height: auto;
  transition: rotate 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), scale 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
  display: block;
}
.home-mascot:hover img {
  rotate: -8deg;
  scale: 1.1;
}
@media (min-width: 1340px) {
  .home-mascot {
    width: 84px;
    margin: 0;
    position: absolute;
    top: -0.4rem;
    left: -116px;
  }
}
.home-visual .packing-log {
  border: 0;
  border-top: 1px solid var(--line-subtle);
  background: none;
  border-radius: 0;
  flex: none;
}

/* Landing panel: wider, and its top edge sits on the rule under "Bio" */
@media (min-width: 1100px) {
  .content-frame.home-frame {
    width: min(100%, 1260px);
  }
  .home-layout {
    gap: clamp(3rem, 6vw, 5.5rem);
  }
  /* The top edge rides the rule under "Bio" until it reaches the top of the screen; the bottom edge always stays
     one page margin above the bottom of the screen, so the panel stretches as the page scrolls.
     --top, --offset and --grow come from the script in index.html. */
  .home-visual {
    top: var(--page-pad);
    height: calc(100svh / var(--zoom) - var(--top, var(--page-pad)) - var(--page-pad) + var(--grow, 0px));
    max-height: none;
    margin-top: var(--offset, 0px);
  }
}
@media (min-width: 1340px) and (max-width: 1519px) {
  .home-mascot {
    width: 56px;
    margin: 0 0 1.1rem;
    position: static;
  }
}

/* Landing mascot: still, with a rubbery wobble every 3s and a typed line in a glass bubble above it */
.content-frame.home-frame {
  --mascot: 76px;
}
@media (min-width: 1100px) {
  .content-frame.home-frame {
    width: min(100%, 1220px);
  }
}
.home-mascot,
.home-mascot:hover {
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: center;
  gap: 0.9rem;
  width: auto;
  margin: 0 0 1.2rem;
  animation: none;
  display: flex;
  position: static;
}
.home-mascot .creature {
  flex: none;
  width: var(--mascot);
  transform-origin: 50% 100%;
  animation: 3s cubic-bezier(0.3, 0.6, 0.3, 1) infinite jelly;
}
.home-mascot .creature img {
  border: 0;
  border-radius: 0;
  filter: drop-shadow(0 12px 14px rgb(0 0 0 / 0.3));
}
@keyframes jelly {
  0%, 30%, 100% { translate: 0 0; scale: 1 1; rotate: 0deg; }
  5% { translate: 0 0; scale: 1.16 0.82; rotate: 0deg; }
  11% { translate: 0 -16px; scale: 0.9 1.12; rotate: -7deg; }
  17% { translate: 0 0; scale: 1.12 0.86; rotate: 5deg; }
  22% { translate: 0 0; scale: 0.96 1.05; rotate: -2deg; }
  26% { translate: 0 0; scale: 1.03 0.98; rotate: 0deg; }
}
.content-frame .home-mascot .creature-bubble {
  background: linear-gradient(135deg, color-mix(in srgb, var(--text-heading) 16%, transparent), color-mix(in srgb, var(--text-heading) 4%, transparent));
  -webkit-backdrop-filter: blur(16px) saturate(170%);
  backdrop-filter: blur(16px) saturate(170%);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28), inset 0 -1px 0 rgb(255 255 255 / 0.05), 0 10px 26px rgb(0 0 0 / 0.28);
  color: var(--text-heading);
  border: 0;
  border-radius: 16px;
  align-items: center;
  min-width: 0;
  max-width: 180px;
  min-height: calc(2 * 1.4em + 1rem);
  margin: 0;
  padding: 0.5rem 0.8rem;
  font-size: 14px;
  line-height: 1.4;
  display: flex;
}
.home-mascot .creature-bubble::after {
  display: none;
}
.home-mascot .creature-bubble span::after {
  content: "";
  background: currentColor;
  vertical-align: -0.12em;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  animation: 1s steps(2) infinite caret;
  display: inline-block;
}
@keyframes caret {
  50% { opacity: 0; }
}
/* Desktop: the mascot stands on the top edge of the packing panel (the script in index.html moves it into
   .home-layout and sets --rule and --panel-left), so nothing sits above the name. */
@media (min-width: 1100px) {
  .home-layout {
    position: relative;
  }
  .content-frame.home-frame {
    --mascot: 84px;
  }
  /* Far right corner of the panel, bubble to its left. */
  .home-layout > .home-mascot,
  .home-layout > .home-mascot:hover {
    flex-direction: row;
    justify-content: flex-end;
    align-items: flex-end;
    gap: 12px;
    width: max-content;
    margin: 0;
    position: absolute;
    top: var(--rule, 6rem);
    left: auto;
    right: 0;
    translate: 0 calc(-100% - 8px);
  }
  /* Upright: no lean toward the cursor here. */
  .home-layout > .home-mascot .creature {
    rotate: 0deg;
  }
}

/* A louder bubble on the packing panel: types "hover over me!" and leaves once the cursor arrives. */
.packing-hint {
  display: none;
}
@media (min-width: 1100px) {
  .content-frame .packing-hint {
    color: #0d1f19;
    font-family: var(--font-ui);
    pointer-events: none;
    z-index: 2;
    background: var(--accent);
    box-shadow: 0 10px 26px rgb(0 0 0 / 0.35), 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
    border-radius: 14px 14px 14px 4px;
    min-width: 2.2em;
    min-height: 2.5em;
    margin: 0;
    padding: 0.55rem 0.85rem;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    transition: opacity 0.35s, scale 0.35s cubic-bezier(0.22, 1, 0.36, 1);
    transform-origin: 0 100%;
    animation:
      0.6s cubic-bezier(0.22, 1, 0.36, 1) 1.5s backwards pop-in,
      2.4s ease-in-out 3.2s infinite packing-nudge;
    display: block;
    position: absolute;
    top: 16px;
    left: 16px;
  }
  .packing-hint span::after {
    content: "";
    background: currentColor;
    vertical-align: -0.12em;
    width: 2px;
    height: 1em;
    margin-left: 2px;
    animation: 1s steps(2) infinite caret;
    display: inline-block;
  }
  .packing-hint.is-gone {
    opacity: 0;
    scale: 0.6;
  }
}
@keyframes packing-nudge {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -5px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .content-frame .packing-hint {
    animation: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .home-mascot .creature,
  .home-mascot .creature-bubble span::after { animation: none; }
}

/* Passions: series / theme / passion node chart */
.theme-graph-figure {
  margin: 0;
}
.theme-graph {
  font-family: var(--font-mono);
  width: 100%;
  height: auto;
  font-size: 12px;
  display: block;
  overflow: visible;
}
.theme-graph .edge {
  fill: none;
  stroke: var(--text-nav);
  stroke-width: 1;
  opacity: 0.28;
  transition: opacity 0.4s, stroke 0.4s;
}
.theme-graph.has-focus .edge:not(.on) {
  opacity: 0.1;
}
.theme-graph .edge.on {
  stroke: var(--accent);
  stroke-dasharray: 4 5;
  opacity: 1;
  animation: 0.9s linear infinite edge-flow;
}
@keyframes edge-flow {
  to { stroke-dashoffset: -9; }
}
.theme-graph .node {
  cursor: pointer;
  outline: none;
  transition: opacity 0.4s;
}
.theme-graph.has-focus .node:not(.on) {
  opacity: 0.35;
}
.theme-graph .node-hit {
  fill: transparent;
}
.theme-graph .node-dot {
  fill: var(--bg);
  stroke: var(--text-nav);
  stroke-width: 1.5;
  transition: fill 0.4s, stroke 0.4s;
}
.theme-graph .node.on .node-dot {
  fill: var(--accent);
  stroke: var(--accent);
}
.theme-graph text {
  fill: var(--text-nav);
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 5px;
  stroke-linejoin: round;
  transition: fill 0.4s;
}
.theme-graph .node-theme text {
  font-size: 11px;
}
.theme-graph .node.on text {
  fill: var(--text-heading);
}
.content-frame .theme-graph-figure figcaption {
  color: var(--text-nav);
  font-family: var(--font-mono);
  flex-direction: column;
  gap: 0.3rem;
  min-height: 4.2em;
  margin-top: 1.2rem;
  font-size: 12px;
  line-height: 1.5;
  display: flex;
}
#theme-readout {
  color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .theme-graph .edge.on { animation: none; }
}

/* Phone intro: the packing fills the screen under the name until the first tap or scroll */
.intro-name,
.intro-hint {
  display: none;
}
@media (max-width: 1099px) {
  .has-intro body {
    overflow: hidden;
  }
  .has-intro .home-visual {
    background: var(--bg);
    z-index: 50;
    flex-direction: column;
    margin: 0;
    padding: max(1.4rem, env(safe-area-inset-top)) 0 max(1rem, env(safe-area-inset-bottom));
    animation: none;
    transition: opacity 0.6s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
    display: flex;
    position: fixed;
    inset: 0;
  }
  .intro-leaving .home-visual {
    opacity: 0;
    transform: translateY(-5%);
    pointer-events: none;
  }
  .has-intro .content-frame .intro-name {
    color: var(--text-heading);
    letter-spacing: -0.03em;
    margin: 0;
    padding: 0 1.25rem 1rem;
    font-size: 2.4rem;
    font-weight: 600;
    line-height: 1.1;
    display: block;
  }
  .has-intro .home-visual canvas {
    border-block: 1px solid var(--line-subtle);
    flex: 1;
    width: 100%;
    min-height: 0;
    display: block;
  }
  .has-intro .home-visual .packing-log {
    height: calc(6 * 1.6em + 1.4rem);
    font-size: 11px;
  }
  .has-intro .content-frame .home-visual-caption {
    color: var(--text-nav);
    font-family: var(--font-ui);
    flex-direction: column;
    gap: 0.2rem;
    margin: 0;
    padding: 0.7rem 1.25rem 0;
    font-size: 14px;
    line-height: 1.4;
    display: flex;
  }
  .has-intro .content-frame .intro-hint {
    color: var(--text-heading);
    font-family: var(--font-ui);
    text-align: center;
    margin: 1rem 0 0;
    font-size: 14px;
    animation: 1.8s ease-in-out infinite intro-hint;
    display: block;
  }
}
@keyframes intro-hint {
  50% { opacity: 0.35; }
}

/* Touch screens have no cursor to run through the packing. */
@media (hover: none) {
  .pointer-only {
    display: none;
  }
}

/* Phones get a one-paragraph default bio; "Long" still has everything. */
.bio-short {
  display: none;
}
@media (max-width: 639px) {
  .bio-short {
    display: block;
  }
  .bio-full {
    display: none;
  }
}

/* Passions on narrow screens: the chart sits right under the intro, above the sections it maps. */
@media (max-width: 1099px) {
  .page-layout:is(:has(#theme-graph), :has(.commit-grid)) {
    flex-direction: column;
    display: flex;
  }
  .page-layout:is(:has(#theme-graph), :has(.commit-grid)) > .page-copy {
    display: contents;
  }
  .page-layout:is(:has(#theme-graph), :has(.commit-grid)) > .page-copy > * {
    order: 2;
  }
  .page-layout:is(:has(#theme-graph), :has(.commit-grid)) > .page-copy > :is(.tabs-back-link, h1, h1 + p) {
    order: 0;
  }
  .page-layout:is(:has(#theme-graph), :has(.commit-grid)) > .page-media {
    order: 1;
    margin: 0.5rem 0 1rem;
    padding: 0;
  }
}

/* Amphi on narrow screens: the mascot sits right under the intro, above the sections. */
@media (max-width: 1099px) {
  .page-layout:has(.creature-stage) {
    flex-direction: column;
    display: flex;
  }
  .page-layout:has(.creature-stage) > :is(.page-copy, .page-media) {
    display: contents;
  }
  .page-layout:has(.creature-stage) > .page-copy > * {
    order: 2;
  }
  .page-layout:has(.creature-stage) > .page-copy > :is(.tabs-back-link, h1) {
    order: 0;
  }
  .page-layout:has(.creature-stage) > .page-media > * {
    order: 3;
  }
  .page-layout:has(.creature-stage) > .page-media > .creature-stage {
    order: 1;
    margin: 0.2rem 0 1.4rem;
  }
  .creature-stage .creature-scene {
    align-items: center;
    min-height: 0;
    padding: 0;
  }
  .creature-stage .creature {
    width: 104px;
  }
  .creature-stage .creature-shadow {
    width: 80px;
  }
  .content-frame .creature-stage figcaption {
    display: none;
  }
  .page-copy > .knockback {
    margin: 0.5rem 0 2rem;
  }
}

/* Open Literacy: "OL." in the serif of the profile picture, centered, one character on each side */
.ol-hero {
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  gap: 0 clamp(0.6rem, 2.5vw, 1.6rem);
  display: grid;
}
.content-frame .ol-wordmark {
  font-family: "Gloock", "DM Serif Display", Didot, "Bodoni MT", serif;
  font-style: italic;
  letter-spacing: -0.01em;
  grid-area: 1 / 2;
  font-size: clamp(5.4rem, 10vw, 8.5rem);
  font-weight: 400;
  line-height: 0.85;
}
/* The two characters become grid items themselves, so they can flank the wordmark. */
.ol-hero .ol-characters {
  display: contents;
}
.ol-hero .ol-character:first-child {
  grid-area: 1 / 1;
  justify-self: end;
}
.ol-hero .ol-character:last-child {
  grid-area: 1 / 3;
  justify-self: start;
}
.content-frame .ol-hero .ol-tagline {
  text-align: center;
  grid-column: 1 / -1;
}

/* Page titles set as each project's own wordmark */
.content-frame .brand-amphi {
  font-family: "Fraunces", var(--font-serif, Georgia), serif;
  font-variation-settings: "opsz" 144;
  letter-spacing: -0.03em;
  font-size: clamp(3.2rem, 9vw, 4.6rem);
  font-weight: 700;
  line-height: 1;
}
.brand-amphi span {
  color: #5ea8ff;
}
.content-frame .brand-roblox {
  font-family: "Montserrat", var(--font-ui), sans-serif;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  font-size: clamp(2.6rem, 8vw, 3.6rem);
  font-weight: 800;
  line-height: 1;
}
/* Open Literacy: the OL block is the title, centered in its column. */
.page-copy > .ol-hero {
  margin: 0.4rem 0 2rem;
}
.content-frame h1.ol-wordmark {
  margin: 0;
}

/* Characters fall into place and settle with a rubbery bounce; their speech bubble pops in after they land. */
@keyframes drop-in {
  0% {
    opacity: 0;
    transform: translateY(-80vh) scale(0.9, 1.14);
    animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.45);
  }
  12% {
    opacity: 1;
  }
  45% {
    transform: translateY(0) scale(1.24, 0.7);
  }
  60% {
    transform: translateY(-28px) scale(0.92, 1.1);
  }
  73% {
    transform: translateY(0) scale(1.11, 0.89);
  }
  84% {
    transform: translateY(-9px) scale(0.98, 1.03);
  }
  93% {
    transform: translateY(0) scale(1.03, 0.98);
  }
}
@keyframes pop-in {
  0% {
    opacity: 0;
    scale: 0.2;
  }
  55% {
    opacity: 1;
    scale: 1.14;
  }
  78% {
    scale: 0.95;
  }
}
.creature img {
  transform-origin: 50% 100%;
  animation: 1.2s ease-out 0.3s both drop-in;
}
.ol-character {
  transform-origin: 50% 100%;
  animation: 1.2s ease-out 0.2s both drop-in;
}
.ol-character:last-child {
  animation-delay: 0.42s;
}
.creature-bubble {
  transform-origin: 50% 100%;
  animation: 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 1.15s both pop-in;
}
/* Behind the phone intro, hold every entrance until it is dismissed. */
.has-intro:not(.intro-leaving) :is(.home-copy > *, .writing-index > section, .creature img, .creature-bubble) {
  animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
  .creature img,
  .ol-character,
  .creature-bubble {
    animation: none;
  }
}

/* Zamp: the company logo (mark in its blue, wordmark in the page's text color) is the title */
.content-frame .brand-zamp {
  line-height: 0;
}
.zamp-logo {
  width: clamp(170px, 48vw, 230px);
  height: auto;
  display: block;
}

/* Zamp on phones: dots drawn over the title logo by pixel-logo.js */
.brand-zamp {
  position: relative;
}
.zamp-dots {
  width: clamp(170px, 48vw, 230px);
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
}

/* Zamp: dotted logo, desktop only */
.pixel-logo {
  display: none;
}
@media (min-width: 1100px) {
  .pixel-logo {
    width: 100%;
    margin: -1rem 0 1.4rem;
    display: block;
  }
}

/* Each project title enters its own way.
   Amphi: the word is typed out letter by letter, then the blue full stop drops in and bounces, ending the sentence. */
.brand-amphi i,
.brand-roblox i {
  font-style: normal;
  display: inline-block;
}
.brand-amphi i {
  animation: 0.45s cubic-bezier(0.22, 1, 0.36, 1) calc(0.25s + var(--n) * 0.11s) both amphi-type;
}
@keyframes amphi-type {
  from {
    opacity: 0;
    transform: translateY(0.18em);
    filter: blur(4px);
  }
}
.brand-amphi span {
  transform-origin: 50% 100%;
  animation: 1.1s ease-out 0.85s both drop-in;
  display: inline-block;
}
/* Roblox: letters are knocked in from the right one after another and skid to a stop past their mark. */
.brand-roblox i {
  transform-origin: 50% 80%;
  cursor: pointer;
  animation: 0.8s both calc(0.15s + var(--n) * 0.07s) knock-in;
}
@keyframes knock-in {
  0% {
    opacity: 0;
    transform: translate(60vw, -30px) rotate(50deg);
    animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1);
  }
  20% {
    opacity: 1;
  }
  58% {
    transform: translate(-12px, 0) rotate(-9deg) scale(0.94, 1.05);
  }
  78% {
    transform: translate(4px, 0) rotate(3deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .brand-amphi i,
  .brand-amphi span,
  .brand-roblox i {
    animation: none;
  }
}

/* Roblox mark (tilted square with a square hole), left of the name; it is knocked around like the letters. */
.brand-roblox .roblox-mark {
  color: #5c82ff;
  vertical-align: -0.12em;
  width: 0.92em;
  margin-right: 0.22em;
}
.roblox-mark svg {
  width: 100%;
  height: auto;
  display: block;
}

/* GitHub: the contribution grid, no container. Columns pop in left to right. */
.commit-figure {
  margin: 0 0 1.6rem;
}
.commit-grid svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}
.commit-grid text {
  fill: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 9px;
}
.commit-grid rect {
  fill: color-mix(in srgb, var(--text-heading) 9%, transparent);
  transform-box: fill-box;
  transform-origin: center;
  animation: pop-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) calc(0.25s + var(--c) * 18ms) backwards;
}
.commit-grid rect[data-l="1"] { fill: #0e5a32; }
.commit-grid rect[data-l="2"] { fill: #0f8a40; }
.commit-grid rect[data-l="3"] { fill: #26b34a; }
.commit-grid rect[data-l="4"] { fill: #4ee06a; }
.commit-grid rect.is-picked {
  stroke: var(--text-heading);
  stroke-width: 1.5;
}
.content-frame .commit-readout,
.content-frame .commit-note {
  color: var(--text-nav);
  font-family: var(--font-ui);
  font-size: 14px;
}
.content-frame .commit-readout {
  margin-top: 0.7rem;
}
@media (prefers-reduced-motion: reduce) {
  .commit-grid rect {
    animation: none;
  }
}
.content-frame .commit-heading {
  color: var(--text-heading);
  font-family: var(--font-ui);
  margin: 0 0 0.5rem;
  font-size: 15px;
  font-weight: 600;
}
.commit-grid.is-claude rect[data-l="1"] { fill: #5c2f20; }
.commit-grid.is-claude rect[data-l="2"] { fill: #944a31; }
.commit-grid.is-claude rect[data-l="3"] { fill: #d97757; }
.commit-grid.is-claude rect[data-l="4"] { fill: #f5a888; }
.content-frame .commit-figure .commit-note {
  margin: 0.3rem 0 0;
}

/* Light and dark toggle, top right of every page */
.theme-toggle {
  color: var(--text-nav);
  cursor: pointer;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--line-subtle);
  border-radius: 50%;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  transition: color 0.2s, scale 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
  display: grid;
  position: fixed;
  top: 14px;
  right: 16px;
}
.theme-toggle:hover {
  color: var(--text-heading);
  scale: 1.08;
}
.theme-toggle:active {
  scale: 0.92;
}
.theme-toggle svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  grid-area: 1 / 1;
  width: 19px;
  height: 19px;
  transition: opacity 0.25s, rotate 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), scale 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
:root[data-theme="dark"] .theme-moon,
:root[data-theme="light"] .theme-sun {
  opacity: 0;
  rotate: 90deg;
  scale: 0.4;
}
.has-intro .theme-toggle,
.has-pop .theme-toggle {
  display: none;
}
:root[data-theme="light"] .commit-grid rect[data-l="1"] { fill: #aee9b9; }
:root[data-theme="light"] .commit-grid rect[data-l="2"] { fill: #56c46d; }
:root[data-theme="light"] .commit-grid rect[data-l="3"] { fill: #2a9a48; }
:root[data-theme="light"] .commit-grid rect[data-l="4"] { fill: #116a2f; }
:root[data-theme="light"] .commit-grid.is-claude rect[data-l="1"] { fill: #f8cdbb; }
:root[data-theme="light"] .commit-grid.is-claude rect[data-l="2"] { fill: #eb9f80; }
:root[data-theme="light"] .commit-grid.is-claude rect[data-l="3"] { fill: #d97757; }
:root[data-theme="light"] .commit-grid.is-claude rect[data-l="4"] { fill: #9c4428; }

/* More titles that enter their own way. */
:is(.brand-civic, .brand-tsa, .brand-research, .brand-github, .brand-passions) i {
  font-style: normal;
  display: inline-block;
}

/* Civic: the wordmark from the app, with the dots of both i's dropped onto it like reports landing on the map. */
.brand-civic {
  font-family: var(--font-ui);
  letter-spacing: -0.05em;
  font-size: clamp(2.8rem, 4.3vw, 3.4rem);
  font-weight: 700;
  line-height: 1.1;
}
.civic-pin {
  display: inline-block;
  position: relative;
}
.civic-pin b {
  --pin: #22c55e;
  background: var(--pin);
  border-radius: 50%;
  width: 0.2em;
  height: 0.2em;
  margin-left: -0.1em;
  animation: 0.95s cubic-bezier(0.22, 1, 0.36, 1) 0.45s backwards drop-in;
  position: absolute;
  top: 0.16em;
  left: 50%;
}
.civic-pin.is-blue b {
  --pin: #3b82f6;
  animation-delay: 0.7s;
}
.civic-pin b::after {
  content: "";
  background: var(--pin);
  opacity: 0;
  border-radius: 50%;
  animation: 2.6s ease-out 1.5s infinite civic-ping;
  position: absolute;
  inset: 0;
}
.civic-pin.is-blue b::after {
  animation-delay: 2.1s;
}
@keyframes civic-ping {
  0% {
    opacity: 0.5;
    scale: 1;
  }
  60%,
  100% {
    opacity: 0;
    scale: 3.4;
  }
}

/* TSA Webmaster: the title arrives as its own source, <h1>TSA Webmaster</h1>, then the tags fold away and it renders. */
.brand-tsa {
  white-space: nowrap;
}
.tsa-tag {
  color: var(--accent);
  font-family: var(--font-mono);
  letter-spacing: 0;
  vertical-align: 0.22em;
  max-width: 5em;
  font-size: 0.42em;
  font-weight: 400;
  animation: 0.7s cubic-bezier(0.22, 1, 0.36, 1) 1.5s both tsa-tag-out;
  display: inline-block;
  overflow: hidden;
}
.tsa-tag:first-child {
  margin-right: 0.5em;
}
.tsa-tag:last-child {
  margin-left: 0.5em;
}
@keyframes tsa-tag-out {
  100% {
    opacity: 0;
    max-width: 0;
    margin: 0;
  }
}
.tsa-text {
  animation: 0.6s ease-out 1.6s backwards tsa-render;
}
@keyframes tsa-render {
  0% {
    color: var(--text-nav);
  }
}

/* Research: the title is found by search. Letters mutate each generation and lock when they match (site.js). */
.brand-research {
  font-family: var(--font-mono);
  letter-spacing: -0.04em;
  font-size: clamp(2.2rem, 3.3vw, 2.6rem);
}
.brand-research i {
  transition: color 0.9s ease-out;
}
.brand-research i.is-open {
  color: var(--text-nav);
  opacity: 0.6;
  transition: none;
}
.brand-research i.is-kept {
  color: var(--accent);
  transition: none;
}
.research-gen {
  color: var(--text-nav);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  margin-top: 0.55rem;
  line-height: 1;
  display: block;
}

/* GitHub: each letter starts as a square on the contribution grid, then the square gives way to the letter. */
.brand-github {
  font-family: var(--font-ui);
  letter-spacing: -0.03em;
}
.brand-github i {
  animation: 0.25s ease calc(0.6s + var(--n) * 90ms) backwards github-letter;
  position: relative;
}
.brand-github i::before {
  content: "";
  background: #26b34a;
  border-radius: 0.11em;
  animation:
    0.5s cubic-bezier(0.34, 1.56, 0.64, 1) calc(0.1s + var(--n) * 90ms) backwards pop-in,
    0.3s ease calc(0.6s + var(--n) * 90ms) forwards github-cell-out;
  position: absolute;
  inset: 0.2em 0.02em 0.14em;
}
.brand-github i:nth-child(3n + 1)::before {
  background: #0f8a40;
}
.brand-github i:nth-child(3n)::before {
  background: #4ee06a;
}
@keyframes github-letter {
  0% {
    color: transparent;
  }
}
@keyframes github-cell-out {
  100% {
    opacity: 0;
    scale: 0.3;
  }
}

/* Passions: scattered letters drift together, then one edge of the chart is drawn under them. */
.brand-passions {
  width: fit-content;
  position: relative;
}
.brand-passions i {
  font-style: italic;
  animation: 1.2s cubic-bezier(0.22, 1, 0.36, 1) calc(0.1s + var(--n) * 55ms) backwards passions-settle;
}
@keyframes passions-settle {
  0% {
    opacity: 0;
    filter: blur(5px);
    translate: var(--x) var(--y);
    rotate: var(--r);
  }
}
.brand-passions::after {
  content: "";
  border-top: 1.5px dashed var(--accent);
  transform-origin: 0 50%;
  animation: 0.9s cubic-bezier(0.22, 1, 0.36, 1) 1s backwards passions-edge;
  position: absolute;
  bottom: -0.08em;
  left: 0;
  right: 0;
}
@keyframes passions-edge {
  0% {
    scale: 0 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  :is(.brand-civic, .brand-github, .brand-passions) :is(i, b),
  .tsa-text,
  .civic-pin b::after,
  .brand-github i::before,
  .brand-passions::after {
    animation: none;
  }
  .brand-github i::before,
  .tsa-tag {
    display: none;
  }
}

/* Right column, when everything in it fits on screen: pinned for the whole scroll and centered top to bottom,
   so it uses the full height of the screen instead of sitting in the top half. site.js adds the class. */
@media (min-width: 1100px) {
  .page-media.is-centered {
    top: var(--page-pad);
    height: calc(100svh / var(--zoom) - 2 * var(--page-pad));
    flex-direction: column;
    justify-content: center;
    margin-top: 0;
    padding-top: 0;
    display: flex;
    position: sticky;
  }
  .page-media.is-centered > :last-child {
    margin-bottom: 0;
  }
}

/* Roblox page, second pass: copy and timeline on the left, the knockback toy on the right where it shows on open.
   Stats sit inside each step as one compact line. */
.page-copy .timeline {
  margin-top: 2.6rem;
}
.page-copy .timeline-step {
  padding: 0 0 2.4rem 2.25rem;
  display: block;
}
.page-copy .timeline-step:last-child {
  padding-bottom: 0.4rem;
}
.content-frame .page-copy .timeline-stat {
  text-align: left;
  flex-flow: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
  min-width: 0;
  margin: 0.7rem 0 0;
  padding: 0;
  display: flex;
}
.page-copy .timeline-stat strong {
  color: #5c82ff;
  font-size: 1.55rem;
  line-height: 1.2;
}
.page-copy .timeline-stat span + strong {
  margin: 0 0 0 0.9rem;
}

/* The timeline is travelled, not shown: a blue arrow starts on the first dot and rides down with the scroll,
   drawing the line behind it and popping each dot as it passes (roblox.js sets --at and .is-reached). */
.timeline.is-tracked::before {
  background: color-mix(in srgb, var(--text-nav) 45%, transparent);
  width: 2px;
  height: max(0px, calc(var(--at, 14px) - 14px));
  animation: none;
  inset: 14px auto auto 4.5px;
  transform: none;
}
.timeline.is-tracked .timeline-step::before {
  opacity: 0;
  scale: 0;
  transition: scale 0.55s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s, transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), background-color 0.3s;
}
.timeline.is-tracked .timeline-step.is-reached::before {
  opacity: 1;
  scale: 1;
}
.timeline.is-tracked .timeline-step.is-reached::before {
  border-color: #5c82ff;
}
.timeline.is-tracked .timeline-step.is-current::before {
  background: #5c82ff;
  box-shadow: 0 0 0 5px rgb(92 130 255 / 0.16);
}
.timeline.is-tracked .timeline-step:hover::before {
  background: #5c82ff;
}
.timeline-arrow {
  pointer-events: none;
  z-index: 1;
  filter: drop-shadow(0 0 6px rgb(92 130 255 / 0.7));
  width: 17px;
  height: 15px;
  position: absolute;
  top: var(--at, 14px);
  left: 5.5px;
  translate: -50% -78%;
}
.timeline-arrow svg {
  fill: #5c82ff;
  width: 100%;
  height: 100%;
  animation: 1.6s ease-in-out infinite arrow-nudge;
  display: block;
}
.timeline.is-done .timeline-arrow svg {
  animation: none;
}
@keyframes arrow-nudge {
  50% {
    translate: 0 3px;
  }
}

/* Knockback: the canvas covers the whole screen (roblox.js moves it to the body), so the block is never cut off
   and flies in front of the text. Only the pad takes clicks. */
.knockback-canvas {
  pointer-events: none;
  z-index: 30;
  width: calc(100vw / var(--zoom));
  height: calc(100vh / var(--zoom));
  position: fixed;
  top: 0;
  left: 0;
}
.page-media > .knockback {
  margin: 0;
}
.page-media .knockback-pad {
  height: clamp(260px, 42vh, 380px);
}
@media (prefers-reduced-motion: reduce) {
  .timeline-arrow svg {
    animation: none;
  }
}

/* Roblox: art from the games, one row under the knockback toy. Each cell's width follows its image's shape,
   so all three share one height. No frames, just a shadow. */
.game-art {
  gap: 14px;
  margin: 2.2rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
}
.game-art li {
  flex: var(--ratio) 1 0;
  min-width: 0;
  margin: 0;
}
.content-frame .game-art a {
  color: inherit;
  text-decoration: none;
  display: block;
}
.content-frame .game-art a:hover span {
  color: var(--text-heading);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.content-frame .game-art img {
  border: 0;
  border-radius: 10px;
  box-shadow: 0 12px 26px rgb(0 0 0 / 0.38);
  width: 100%;
  height: auto;
  transition: scale 0.4s cubic-bezier(0.22, 1, 0.36, 1), rotate 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  display: block;
}
.content-frame .game-art li:hover img {
  rotate: -2deg;
  scale: 1.05;
}
.game-art span {
  color: var(--text-nav);
  font-family: var(--font-ui);
  margin-top: 0.55rem;
  font-size: 13px;
  line-height: 1.3;
  display: block;
}
@media (max-width: 1099px) {
  .game-art {
    gap: 10px;
    margin: 0 0 2.4rem;
  }
  .game-art span {
    font-size: 12px;
  }
}

/* FBLA: outreach. A line reaches out from the title and ends in an arrowhead. */
.brand-fbla {
  font-family: var(--font-ui);
  letter-spacing: 0.04em;
  align-items: center;
  gap: 0.45em;
  font-weight: 800;
  display: flex;
}
.fbla-reach {
  background: var(--accent);
  transform-origin: 0;
  flex: 0 1 4.5em;
  height: 3px;
  animation: 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.9s both fbla-reach;
  position: relative;
}
.fbla-reach::after {
  border: 0.16em solid transparent;
  border-left: 0.26em solid var(--accent);
  content: "";
  position: absolute;
  top: 50%;
  left: 100%;
  translate: -2px -50%;
}
@keyframes fbla-reach {
  from {
    transform: scaleX(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .fbla-reach {
    animation: none;
  }
}

/* FBLA crest: lifted from fbla.org, so no frame, only a shadow. */
.content-frame .fbla-crest {
  filter: drop-shadow(0 14px 26px rgb(0 0 0 / 0.38));
  border: 0;
  width: 150px;
  height: auto;
  margin: 0 auto 2rem;
  display: block;
}
@media (max-width: 1099px) {
  .content-frame .fbla-crest {
    width: 112px;
    margin: 0 0 1.6rem;
  }
}
