:root {
  /* Color system */
  --bg: #fcfcfc;
  --fg: #171714;
  --muted: #999999;
  --line: #d9dad6;
  --dark: #0b0b0a;
  --dark-soft: #111110;

  /* Layout system: viewport-relative first, rem bounds second. */
  --sidebar-width: clamp(18rem, 27vw, 26.25rem);
  --sidebar-rail-width: 4.5rem;
  --page-pad: clamp(1.25rem, 3.2vw, 3.25rem);
  --content-width: 82.5rem;

  /* Spacing scale */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 5rem;
  --space-10: 6rem;

  /* Type scale */
  --text-xs: .4375rem;
  --text-sm: .5rem;
  --text-meta: .5625rem;
  --text-body-sm: .6875rem;
  --text-body: .875rem;
  --text-body-lg: .9375rem;

  --sans: Inter, Helvetica, Arial, sans-serif;
  --mono: "DM Mono", monospace;
  /* Teste: aplicado apenas nos títulos grandes (ver seletores com
     font-family: var(--display) abaixo) — textos corridos e microtextos
     seguem em --sans. */
  --display: "roc-grotesk", Inter, Helvetica, Arial, sans-serif;
}

/* Transição nativa entre páginas (View Transitions API, cross-document).
   Funciona hoje em Chrome/Edge; em navegadores sem suporte (Safari,
   Firefox) a navegação simplesmente continua normal, sem efeito — não
   quebra nada. Respeita a preferência de menos animação do sistema, como
   as demais animações do site (ver reducedMotion em assets/js/script.js). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

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

html {
  scroll-behavior: smooth;
}

/* Lenis smooth scroll: required classes, see site/assets/js/lenis.min.js */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

/* Scroll reveal: elements fade + rise into view, see site/assets/js/script.js */
[data-reveal] {
  opacity: 0;
  transform: translateY(1.75rem);
  transition: opacity .7s cubic-bezier(.16, .84, .44, 1), transform .7s cubic-bezier(.16, .84, .44, 1);
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: translateY(0);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-weight: 500;
  cursor: none;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  opacity: .55;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.035'/%3E%3C/svg%3E");
}

a {
  color: inherit;
  text-decoration: none;
}

.section {
  position: relative;
  padding-inline: var(--page-pad);
}

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

.content {
  width: min(100%, var(--content-width));
  margin-inline: auto;
  min-width: 0;
}

.eyebrow,
.kicker {
  margin: 0;
  color: var(--muted);
  font: var(--text-meta) var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* Sidebar */

.mobile-menu-bar,
.mobile-menu {
  display: none;
}

.sidebar {
  position: fixed;
  z-index: 50;
  inset: 0 auto 0 0;
  width: var(--sidebar-width);
  padding: 1.625rem clamp(1.375rem, 2vw, 2rem);
  overflow: hidden;
  border-right: 1px solid var(--line);
  background: #ffffff;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.sidebar-content {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
  /* Fades out fast (no delay) the moment collapse starts, so it's fully
     invisible well before .sidebar finishes narrowing to the rail — its
     text never has to visibly reflow into a cramped column. Reversed
     below with a delay, so it only reappears once the rail is most of
     the way back open. */
  opacity: 1;
  transition: opacity .35s ease .15s;
}

/* Collapse/expand toggle: a sibling of .sidebar, not a child of it — it
   used to live inside .sidebar and straddle its right edge via a negative
   offset, but .sidebar has overflow: hidden (to mask the content sliding
   shut) which clipped it there. Positioned fixed to the viewport instead,
   it tracks the sidebar's own width via the same --sidebar-width /
   --sidebar-rail-width custom properties, so it still glides along in sync
   as the sidebar transitions, just no longer at risk of being clipped by
   it. Kept deliberately quiet — a thin outline, page-colored fill — so it
   reads as a small utility control, not a loud button. */
.sidebar-collapse-toggle {
  position: fixed;
  z-index: 90;
  top: 50%;
  left: var(--sidebar-width);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: #ffffff;
  color: var(--muted);
  cursor: none;
  box-shadow: 0 .125rem .375rem rgba(11, 11, 10, .07);
  transform: translate(-50%, -50%);
  transition: left .5s cubic-bezier(.16, .84, .44, 1), background .2s ease, color .2s ease, border-color .2s ease, box-shadow .2s ease;
}

body.sidebar-collapsed .sidebar-collapse-toggle {
  left: var(--sidebar-rail-width);
}

.sidebar-collapse-toggle:hover {
  background: var(--fg);
  border-color: var(--fg);
  color: #ffffff;
  box-shadow: 0 .25rem .625rem rgba(11, 11, 10, .16);
}

.sidebar-collapse-toggle svg {
  width: .5625rem;
  height: .5625rem;
  transition: transform .5s cubic-bezier(.16, .84, .44, 1);
}

body.sidebar-collapsed .sidebar-collapse-toggle svg {
  transform: rotate(180deg);
}

/* Rail mark: the only thing left in the collapsed sidebar besides the
   toggle — the spinning logo mark, doubling as a way back to the top. Sits
   opposite .sidebar-content (see its own opacity rules below): invisible
   and out of the tab order while expanded, fading in once collapsed so the
   thin rail isn't just a blank strip. */
.sidebar-rail-mark {
  position: fixed;
  z-index: 51;
  top: 1.75rem;
  left: 0;
  width: var(--sidebar-rail-width);
  display: flex;
  justify-content: center;
  font-size: 1.25rem;
  color: var(--fg);
  opacity: 0;
  /* Invisible while expanded, per the comment above — but opacity alone
     doesn't stop it from catching clicks/hover. Left clickable, this fixed,
     always-present element silently sat on top of whatever the expanded
     sidebar renders in that same top-left corner (e.g. the logo), stealing
     the occasional hover/click without ever showing why. */
  pointer-events: none;
  transition: opacity .2s ease;
}

body.sidebar-collapsed .sidebar-rail-mark {
  opacity: 1;
  pointer-events: auto;
  transition: opacity .4s ease .2s;
}

/* Rail clock: the collapsed rail's other anchor point, mirroring the mark
   at its top — otherwise the base of the thin rail is just empty. */
.sidebar-rail-clock {
  position: fixed;
  z-index: 51;
  bottom: 1.75rem;
  left: 0;
  width: var(--sidebar-rail-width);
  text-align: center;
  font-family: var(--mono);
  font-size: var(--text-xs);
  letter-spacing: .06em;
  color: var(--muted);
  opacity: 0;
  /* Purely decorative (aria-hidden, no link) at every width, but still a
     fixed, always-present element sitting at the bottom-left corner —
     exactly where the expanded sidebar's own nav links (Home/Work) live.
     Without this, it silently ate hover/clicks meant for those links even
     while fully invisible. */
  pointer-events: none;
  transition: opacity .2s ease;
}

body.sidebar-collapsed .sidebar-rail-clock {
  opacity: 1;
  transition: opacity .4s ease .2s;
}

.sidebar-identity {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
}

.sidebar-logo {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: .875rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.045em;
}

/* Logo mark: flat SVG spun on its vertical axis, left to right */
.sidebar-mark {
  display: inline-block;
  height: 1em;
  width: auto;
  aspect-ratio: 27.37 / 47.8;
  flex-shrink: 0;
  animation: sidebar-mark-spin 4s linear infinite;
}

.sidebar-mark svg {
  display: block;
  width: 100%;
  height: 100%;
}

.sidebar-mark polygon {
  fill: currentColor;
}

@keyframes sidebar-mark-spin {
  from {
    transform: perspective(12rem) rotateY(0deg);
  }
  to {
    transform: perspective(12rem) rotateY(360deg);
  }
}

.sidebar-location,
.listening-head,
.listening-track span,
.sidebar-nav,
.sidebar-clock,
.sidebar-date {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.sidebar-location {
  color: var(--muted);
  font-size: var(--text-meta);
  white-space: nowrap;
  text-align: right;
}

.sidebar-middle {
  width: 100%;
  margin: auto 0;
  padding: 12vh 0;
}

.working-module {
  width: 100%;
  margin-bottom: clamp(2rem, 4vh, 3.5rem);
  border-top: 1px solid var(--line);
}

.working-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.working-dot {
  width: .3125rem;
  height: .3125rem;
  border-radius: 50%;
  background: var(--fg);
  animation: sidebar-pulse 1.8s ease-in-out infinite;
}

.working-content {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  padding: 0 0 var(--space-4);
  font-size: var(--text-sm);
  line-height: 1.35;
}

.working-content span {
  display: block;
}

.working-content p {
  margin: 0;
  color: #55524c;
  font-size: var(--text-body-sm);
  line-height: 1.55;
}

.working-content small {
  margin-top: .625rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.listening-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--muted);
  font-size: var(--text-meta);
  border-top: 1px solid var(--line);
  padding: var(--space-3) 0 0;
}

.live-dot {
  width: .3125rem;
  height: .3125rem;
  border-radius: 50%;
  background: var(--fg);
  animation: sidebar-pulse 1.8s ease-in-out infinite;
}

.listening-track {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4) 0 1rem;
}

.listening-track strong {
  font-size: var(--text-body);
  line-height: 1.1;
}

.listening-track span {
  color: var(--muted);
  font-size: var(--text-sm);
}

#spectrogram {
  display: block;
  width: 100%;
  height: 5.75rem;
}

.sidebar-bottom {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-3);
  align-items: end;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  font-size: var(--text-meta);
}

/* The text itself is tiny (--text-meta), so the old approach — spacing
   between items via the container's gap alone — left almost no real hit
   area: just the ~9px text line, with an unclickable dead zone in the gap
   above and below it. Padding moves that same spacing inside each link's
   own box instead, so the whole gap between items is still hoverable, not
   just the glyphs themselves. */
.sidebar-nav a {
  position: relative;
  width: max-content;
  padding: .25rem 0;
  transition: opacity .2s ease;
}

.sidebar-nav:hover a:not(:hover) {
  opacity: .35;
}

/* Current-page marker: a small dot before the label, shared by every nav
   list (desktop sidebar, its collapsed-state top bar, mobile overlay below). */
.sidebar-nav a.is-current,
.site-header-nav a.is-current {
  padding-left: .75rem;
}

.sidebar-nav a.is-current::before,
.site-header-nav a.is-current::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: .3125rem;
  height: .3125rem;
  transform: translateY(-50%);
  border-radius: 50%;
  background: currentColor;
}

.sidebar-bottom-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .25rem;
}

.sidebar-date,
.sidebar-clock {
  color: var(--muted);
  font-size: var(--text-meta);
}

main {
  margin-left: var(--sidebar-width);
  min-width: 0;
}

/* Sidebar collapse: present on every page, not just Home (Home just
   defaults to open — see $sidebarDefaultCollapsed in templates/header.php).
   The rail-only state below, and the compact top bar that takes over
   navigation while the sidebar is collapsed. Desktop only — below the
   50rem breakpoint the sidebar is already a compact mobile header (see the
   max-width: 50rem block) and this toggle plays no part in it. */
@media (min-width: 50.0625rem) {
  .sidebar {
    transition: width .5s cubic-bezier(.16, .84, .44, 1);
  }

  main {
    transition: margin-left .5s cubic-bezier(.16, .84, .44, 1);
  }

  .section--closing {
    transition: margin-left .5s cubic-bezier(.16, .84, .44, 1);
  }

  body.sidebar-collapsed .sidebar {
    width: var(--sidebar-rail-width);
  }

  body.sidebar-collapsed .sidebar-content {
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
  }

  body.sidebar-collapsed main {
    margin-left: var(--sidebar-rail-width);
  }

  body.sidebar-collapsed .section--closing {
    margin-left: var(--sidebar-rail-width);
  }

  /* The editorial gallery has the room for a third column once the rail
     frees up the width the full sidebar was reserving. */
  body.sidebar-collapsed .editorial-grid {
    columns: 3;
  }

  /* Same idea for the hero portrait: a bit bigger and shifted further
     right, taking advantage of the extra width the rail frees up. Ratio
     kept identical to the base 24vw / 38.2vw (~22:35). */
  body.sidebar-collapsed .about-portrait-wrap {
    left: 64%;
    width: 26vw;
    height: 41.4vw;
  }

  /* Animates from 0 to the bar's real content height (kept in sync by a
     ResizeObserver in script.js, via --sidebar-topbar-height) rather than
     the usual grid-template-rows: 0fr/1fr trick — that trick relies on the
     grid container being auto-sized, and for a single flexible track in an
     indefinite-size container the spec falls back to that track's
     max-content size, so it never actually reached 0 here. Measuring the
     real height sidesteps that entirely and also keeps the transition's
     timing honest (no animating through empty overflow past the content's
     actual height). */
  .sidebar-topbar-wrap {
    max-height: 0;
    overflow: hidden;
    margin-left: var(--sidebar-rail-width);
    transition: max-height .5s cubic-bezier(.16, .84, .44, 1);
  }

  body.sidebar-collapsed .sidebar-topbar-wrap {
    max-height: var(--sidebar-topbar-height, 16rem);
  }

  .sidebar-topbar {
    opacity: 0;
    /* A border-bottom always renders at its full width even while the
       wrapper above is clipping it to zero height — border thickness isn't
       part of what's being clipped. Left transparent until the bar is
       actually shown, so an expanded sidebar never shows a stray hairline
       where the (invisible) top bar would be. */
    border-bottom-color: transparent;
    transition: opacity .25s ease, border-bottom-color .25s ease;
  }

  body.sidebar-collapsed .sidebar-topbar {
    opacity: 1;
    border-bottom-color: var(--line);
    transition: opacity .4s ease .2s, border-bottom-color .4s ease .2s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar,
  .sidebar-content,
  .sidebar-collapse-toggle,
  .sidebar-collapse-toggle svg,
  .sidebar-rail-mark,
  .sidebar-rail-clock,
  main,
  .section--closing,
  .sidebar-topbar-wrap,
  .sidebar-topbar,
  .about-portrait-wrap {
    transition: none !important;
  }
}

/* Sidebar top bar: the compact bar that takes over navigation whenever the
   sidebar is collapsed (see the @media (min-width: 50.0625rem) block
   above). Two tiers, matching the sidebar's own contrast between primary
   and secondary information: a quiet meta row on top (location, date,
   live clock, Last.fm) echoing the sidebar in a smaller/muted register,
   and the logo + nav below it, kept as the visually dominant row. */
.sidebar-topbar {
  position: relative;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--page-pad) var(--space-5);
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}

.site-header-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  color: var(--muted);
  font: var(--text-xs) var(--mono);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.site-header-meta-group {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.site-header-listening {
  display: inline-flex;
  align-items: center;
  gap: .4375rem;
  max-width: min(40vw, 22rem);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.site-header-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.site-header-logo {
  display: inline-flex;
  font-size: var(--text-body-lg);
  font-weight: 600;
}

.site-header-nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 1.75rem);
  font: 600 var(--text-body-sm) var(--mono);
  color: var(--fg);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.site-header-nav a {
  position: relative;
  transition: opacity .2s ease;
}

.site-header-nav a:hover {
  opacity: .55;
}

/* About */

.section--about {
  min-height: 100svh;
  padding-top: 10vh;
  padding-bottom: 7vh;
  overflow: hidden;
}

.section--about .content {
  position: relative;
  min-height: calc(100svh - 17vh);
  display: flex;
  flex-direction: column;
}

/* Intentionally no z-index here: .content must stay in the same stacking
   context as .about-portrait-wrap (below) so .statement's mix-blend-mode
   can react to the photo behind it, not just to .content's own background.
   Draw order between the two still comes out right because the portrait
   markup comes first in the HTML. */
.statement {
  max-width: 68.75rem;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2.375rem, 6.2vw, 6rem);
  font-weight: 400;
  line-height: .94;
  letter-spacing: -.065em;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  color: #fff;
  mix-blend-mode: difference;
}

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

/* Letter-by-letter reveal on load, see site/assets/js/script.js */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.reveal-letters .letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(.28em);
  transition: opacity .5s ease, transform .5s ease;
}

.reveal-letters.is-revealed .letter {
  opacity: 1;
  transform: translateY(0);
}

.text-link {
  border-bottom: 1px solid var(--fg);
}

.about-detail {
  margin-top: auto;
  padding-top: 10vh;
}

.detail-meta {
  display: grid;
  align-content: start;
  gap: var(--space-2);
  color: var(--muted);
  font: var(--text-meta) var(--mono);
  text-transform: uppercase;
}


.about-portrait-wrap {
  position: absolute;
  z-index: 0;
  left: 60%;
  top: 0;
  width: 24vw;
  height: 38.2vw;
  transform: translate3d(-50%, var(--portrait-y, 0vw), 0);
  will-change: transform;
  pointer-events: none;
  overflow: hidden;
  transition: left .5s cubic-bezier(.16, .84, .44, 1), width .5s cubic-bezier(.16, .84, .44, 1), height .5s cubic-bezier(.16, .84, .44, 1);
}

.about-portrait {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
  filter: grayscale(100%);
}

.about-grain-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: .58;
  mix-blend-mode: multiply;
  image-rendering: pixelated;
}

/* Large statement block */
.section--statement {
  --statement-bg: #171714;
  --statement-fg: #fefcf9;
  --statement-muted: #8d8e88;
  --statement-line: #343430;
  padding-top: clamp(7rem, 13vw, 13rem);
  padding-bottom: clamp(7rem, 13vw, 13rem);
  overflow: hidden;
  background: var(--statement-bg);
  color: var(--statement-fg);
  border-top-color: var(--statement-line);
}

.statement-block {
  max-width: 68rem;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2.35rem, 4vw, 4.5rem);
  line-height: .98;
  letter-spacing: -.06em;
  font-weight: 400;
}

.statement-block em {
  font-style: italic;
}

.statement-block span {
  color: var(--statement-muted);
}

.statement-block .text-link {
  border-bottom: none;
  text-decoration-line: underline;
  text-decoration-color: currentColor;
  text-decoration-thickness: .03em;
  text-underline-offset: .04em;
  transition: opacity .25s ease;
}

/* Este link usa o próprio sublinhado (acima) como estilo fixo, em vez do
   traço animado em hover que .text-link ganha em telas com mouse (ver
   .text-link::after) — sem isso, os dois sublinhados ficam visíveis ao
   mesmo tempo, bem próximos um do outro. */
.statement-block .text-link::after {
  content: none;
}

.statement-block .text-link:hover {
  opacity: .55;
}

/* Work / archive */

.section--archive {
  padding-top: 16vh;
  padding-bottom: 6vh;
}

.archive-intro {
  display: grid;
  grid-template-columns: 5% minmax(0, 1fr) 18% 3%;
  gap: clamp(1rem, 1.6vw, 1.5rem);
  align-items: end;
}

.archive-heading {
  grid-column: 1 / 3;
}

.archive-intro h2,
.gallery-head h2 {
  margin: var(--space-5) 0 0;
  font-family: var(--display);
  font-size: clamp(2.7rem, 5.75vw, 5.85rem);
  line-height: .85;
  letter-spacing: -.075em;
  font-weight: 400;
}

.archive-intro h2 span,
.gallery-head h2 span {
  color: var(--muted);
}

.archive-note {
  max-width: 18.125rem;
  margin: 0;
  color: var(--muted);
  font-size: .6875rem;
  line-height: 1.5;
}

.archive-list {
  margin-top: 15vh;
  border-top: 1px solid var(--line);
}

.archive-item {
  position: relative;
  min-height: 30vh;
  padding: 1.125rem 0;
  display: grid;
  grid-template-columns: 5% minmax(0, 1fr) 18% 3%;
  gap: clamp(1rem, 1.6vw, 1.5rem);
  align-items: start;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  transition: color .35s ease, padding .45s ease;
}

.archive-item::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: auto 0 0;
  height: 0;
  background: var(--hover-bg, var(--fg));
  transition: height .45s cubic-bezier(.2, .8, .2, 1);
}

.archive-item:hover {
  padding-inline: .875rem;
  color: #e9e9e4;
}

.archive-item:hover::before {
  height: 100%;
}

.archive-item:hover .archive-title,
.archive-item:hover .archive-arrow {
  color: #e9e9e4;
}

.archive-item:hover .archive-number,
.archive-item:hover .archive-info > span {
  color: #aaa;
}

.archive-item:hover .archive-info small {
  color: #ccc;
}

.archive-number,
.archive-info > span {
  color: var(--muted);
  font: var(--text-meta) var(--mono);
  text-transform: uppercase;
}

.archive-item:hover .archive-number,
.archive-item:hover .archive-info > span {
  color: #aaa;
}

.archive-title {
  font-family: var(--display);
  font-size: clamp(3.25rem, 8.5vw, 8.25rem);
  font-weight: 400;
  line-height: .78;
  letter-spacing: -.08em;
}

.archive-info {
  align-self: end;
  margin-top: 15vh;
}

.archive-info small {
  display: block;
  max-width: 14.6875rem;
  margin-top: var(--space-3);
  color: #666;
  font-size: .6875rem;
  line-height: 1.5;
}

.archive-item:hover .archive-info small {
  color: #ccc;
}

.archive-arrow {
  align-self: end;
  font-size: 1.125rem;
}

/* Field Notes */

.section--field-notes {
  position: relative;
  padding-top: 9vh;
  padding-bottom: 10vh;
  color: #f1efe9;
  border-top: 1px solid rgba(255,255,255,.12);
  overflow: hidden;
}

.section--field-notes::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  left: calc(-1 * var(--page-pad));
  width: calc(100% + var(--page-pad));
  background: var(--dark);
}

.section--field-notes .content {
  position: relative;
  z-index: 1;
}

.section--field-notes .kicker,
.section--field-notes .field-notes-head > p {
  color: rgba(241,239,233,.48);
}

.field-notes-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-bottom: clamp(2.5rem, 6vh, 3.625rem);
}

.field-notes-head h2 {
  margin: var(--space-3) 0 0;
  font-family: var(--display);
  font-size: clamp(3rem, 7vw, 6.5rem);
  line-height: .88;
  letter-spacing: -.07em;
  font-weight: 400;
}

.field-notes-head > p {
  margin: 0 0 .3125rem;
  font: var(--text-meta) var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.field-notes-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(20rem, .88fr);
  min-height: 55vh;
  border-top: 1px solid rgba(255,255,255,.16);
  border-bottom: 1px solid rgba(255,255,255,.16);
  background: var(--dark);
}

.field-note-feature {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 55vh;
  padding: clamp(1.5rem, 3vw, 2.75rem);
  background: var(--dark-soft);
  border-right: 1px solid rgba(255,255,255,.16);
}

.field-note-tag {
  align-self: flex-start;
  margin-bottom: auto;
  color: rgba(241,239,233,.48);
  font: var(--text-meta) var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.field-note-feature h3 {
  margin: 0 0 1.375rem;
  font-family: var(--display);
  font-size: clamp(2.375rem, 5vw, 4.75rem);
  line-height: .9;
  letter-spacing: -.065em;
  font-weight: 400;
}

.field-note-feature p {
  max-width: 26.875rem;
  margin: 0 0 1.875rem;
  color: rgba(241,239,233,.62);
  font-size: var(--text-body);
  line-height: 1.55;
}

.field-note-feature a {
  width: fit-content;
  color: #f1efe9;
  font: .625rem var(--mono);
  letter-spacing: .05em;
  text-transform: uppercase;
  border-bottom: 1px solid rgba(241,239,233,.45);
  padding-bottom: var(--space-1);
}

.field-note-list {
  display: flex;
  flex-direction: column;
}

.field-note-list a {
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 1.125rem;
  padding: 1.75rem clamp(1.25rem, 2vw, 1.875rem);
  color: #f1efe9;
  border-bottom: 1px solid rgba(255,255,255,.12);
  transition: background .25s ease;
}

.field-note-list a:last-child {
  border-bottom: 0;
}

.field-note-list a:hover {
  background: rgba(255,255,255,.045);
}

.field-note-list a > span {
  grid-row: 1 / span 2;
  color: rgba(241,239,233,.38);
  font: var(--text-meta) var(--mono);
  letter-spacing: .05em;
}

.field-note-list strong {
  font-size: 1.0625rem;
  line-height: 1.15;
  font-weight: 500;
  letter-spacing: -.02em;
}

.field-note-list small {
  margin-top: var(--space-2);
  color: rgba(241,239,233,.42);
  font: var(--text-meta) var(--mono);
  letter-spacing: .04em;
  text-transform: uppercase;
}

.field-note-list .field-notes-blog-link {
  grid-template-columns: 2.25rem minmax(0, 1fr);
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 0;
  color: #f1efe9;
  background: transparent;
}

.field-note-list .field-notes-blog-link:hover {
  background: rgba(255,255,255,.045);
}

.field-note-list .field-notes-blog-link > span {
  grid-row: 1;
  color: rgba(241,239,233,.52);
}

.field-note-list .field-notes-blog-link strong {
  align-self: center;
  font: .625rem var(--mono);
  letter-spacing: .05em;
  text-transform: uppercase;
}

/* Gallery */

.section--gallery {
  padding-top: 6vh;
  padding-bottom: 22vh;
}

.gallery-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-2);
}

/* Each of the 2 columns stacks its own pieces independently (normal flow,
   never overlaps): a shorter piece in one column is immediately followed
   by the next piece in that same column, without waiting for the other
   columns to reach the same height. --gallery-gap drives both the column
   gap and the vertical gap between stacked pieces, so spacing is always
   identical in both directions — a real, organized mosaic.

   CSS multi-column (below) is only the no-JS fallback: its "balance"
   algorithm approximates equal column heights but can't guarantee a piece
   joins the shortest column, so with a handful of tall/uneven pieces it
   regularly strands one column much taller than the other. script.js
   measures each piece and rebuilds the grid into real .editorial-grid-col
   columns (assigning every piece to whichever column is currently
   shortest), then adds .is-masonry — see "True masonry" in script.js. */
.editorial-grid {
  --gallery-gap: clamp(.75rem, 2vw, 1.5rem);
  columns: 2;
  column-gap: var(--gallery-gap);
  margin-top: 15vh;
}

.editorial-grid.is-masonry {
  display: flex;
  align-items: flex-start;
  columns: initial;
}

.editorial-grid-col {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  gap: var(--gallery-gap);
}

.piece {
  display: inline-block;
  width: 100%;
  margin: 0 0 var(--gallery-gap);
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

.editorial-grid-col .piece {
  margin-bottom: 0;
}

.piece-media {
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--line);
  background: transparent;
}

.piece-fields {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  color: var(--muted);
  font: var(--text-meta) var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.piece-fields span:last-child {
  text-align: right;
}

/* Gallery CTA: a 1770×996 card mixed into the mosaic pool, echoing the
   Freelancing archive-item layout (title top-left, text bottom-left,
   arrow bottom-right) but sized to sit among the gallery pieces. */
.gallery-cta {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  aspect-ratio: 1770 / 996;
  padding: var(--space-3);
  background: var(--dark);
  border: 1px solid rgba(255,255,255,.16);
  color: #f1efe9;
  text-decoration: none;
  transition: background .25s ease;
}

.gallery-cta:hover {
  background: var(--dark-soft);
}

.gallery-cta-title {
  align-self: flex-start;
  font-family: var(--display);
  font-size: clamp(1.375rem, 7vw, 2.5rem);
  line-height: .85;
  letter-spacing: -.075em;
  font-weight: 400;
}

.gallery-cta-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-2);
}

.gallery-cta-text {
  max-width: 11rem;
  color: rgba(241,239,233,.62);
  font-size: .6875rem;
  line-height: 1.5;
}

.gallery-cta-arrow {
  font-size: 1.125rem;
}

/* Closing */

.section--closing {
  min-height: 65svh;
  padding-top: 11vh;
  padding-bottom: 1.625rem;
  display: grid;
  grid-template-rows: 1fr auto;
  background: var(--dark);
  color: #f1efe9;
}

.section--closing .kicker {
  color: #f1efe9;
}

.closing-content {
  grid-row: 1;
}

.closing-title {
  margin-top: 7vh;
  display: flex;
  flex-direction: column;
  color: #f1efe9;
  font-family: var(--display);
  font-size: clamp(3rem, 7vw, 7rem);
  font-weight: 400;
  line-height: .78;
  letter-spacing: -.085em;
}

/* Same muted/highlight pairing used elsewhere on dark sections (see
   .statement-block span, .portfolio-hero-title-muted): the lead-in stays
   muted, the payoff word keeps the full-bright color. */
.closing-title span:first-child {
  color: #8d8e88;
}

.socials {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) clamp(1.25rem, 2.5vw, 1.875rem);
  margin-top: 8vh;
  font: .625rem var(--mono);
  text-transform: lowercase;
}

.socials a {
  color: #f1efe9;
  padding-bottom: .375rem;
  border-bottom: 1px solid rgba(241,239,233,.6);
}

.socials span {
  margin-left: .875rem;
}

.section--closing footer {
  grid-row: 2;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-5);
  padding-top: .8125rem;
  border-top: 1px solid rgba(241,239,233,.2);
  color: rgba(241,239,233,.52);
  background: transparent;
  font: var(--text-meta) var(--mono);
}

.section--closing footer a {
  color: #f1efe9;
  text-align: right;
}

.section--closing .copyright {
  text-transform: uppercase;
}

/* Cursor */

.cursor {
  position: fixed;
  z-index: 100;
  width: .625rem;
  height: .625rem;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%);
  background: #fff;
  mix-blend-mode: difference;
  transition: width .3s cubic-bezier(.2, .8, .2, 1), height .3s cubic-bezier(.2, .8, .2, 1);
}

body.hovering .cursor {
  width: .875rem;
  height: .875rem;
}

/* Contextual label (e.g. "View", "Read"): the cursor grows into a pill and
   shows it on links tagged with data-cursor-label, see assets/js/script.js.
   Because .cursor blends the whole dot+label as one unit (mix-blend-mode
   already applies to its full composited box), the white pill and this
   dark text invert together — a light label on a dark pill over light
   sections, a dark label on a light pill over dark ones, no per-section
   overrides needed. */
.cursor-label {
  opacity: 0;
  transform: scale(.6);
  font: 600 .5625rem var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dark);
  white-space: nowrap;
  transition: opacity .2s ease, transform .2s ease;
}

body.hovering-label .cursor {
  width: 4.25rem;
  height: 4.25rem;
}

body.hovering-label .cursor-label {
  opacity: 1;
  transform: scale(1);
  transition-delay: .05s;
}

/* Motion */

@keyframes sidebar-pulse {
  0%, 100% {
    opacity: .35;
    transform: scale(.85);
  }

  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Responsive */

@media (max-width: 68.75rem) {
  :root {
    --sidebar-width: clamp(15.625rem, 24vw, 26.25rem);
  }

  .archive-item {
    grid-template-columns: 7% minmax(0, 1fr) 16% 3%;
  }

  .archive-intro {
    grid-template-columns: 7% minmax(0, 1fr) 16% 3%;
  }
}

@media (max-width: 50rem) {
  :root {
    --page-pad: clamp(1rem, 4.5vw, 1.25rem);
  }

  body {
    cursor: auto;
    overflow-x: hidden;
  }

  .cursor {
    display: none;
  }

  /* Hamburger navigation */
  .mobile-menu-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 1.5rem;
    position: relative;
    z-index: 60;
  }

  .mobile-menu-bar .sidebar-logo {
    display: inline-flex;
  }

  .menu-toggle {
    position: relative;
    width: 2.125rem;
    height: 1.75rem;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
  }

  .menu-toggle span {
    position: absolute;
    left: .3125rem;
    width: 1.5rem;
    height: 1px;
    background: var(--fg);
    transition: transform .3s ease, top .3s ease;
  }

  .menu-toggle span:first-child {
    top: .625rem;
  }

  .menu-toggle span:last-child {
    top: 1.0625rem;
  }

  .sidebar.menu-open .menu-toggle span:first-child {
    top: .875rem;
    transform: rotate(45deg);
  }

  .sidebar.menu-open .menu-toggle span:last-child {
    top: .875rem;
    transform: rotate(-45deg);
  }

  .mobile-menu {
    display: flex;
    flex-direction: column;
    position: fixed;
    z-index: 40;
    inset: 0;
    width: 100%;
    min-height: 100svh;
    padding: 5rem var(--page-pad) 1.5rem;
    background: transparent;
    border-bottom: 1px solid var(--line);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-.5rem);
    transition: opacity .25s ease, transform .3s ease, visibility .25s ease;
  }

  .sidebar.menu-open .mobile-menu {
    background: rgba(254,252,249,.97);
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }

  .mobile-menu-nav {
    display: flex;
    flex-direction: column;
  }

  .mobile-menu-nav a {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: .75rem 0;
    border-bottom: 1px solid var(--line);
    font-size: 1.875rem;
    line-height: 1;
    letter-spacing: -.055em;
  }

  .mobile-menu-nav a:first-child {
    border-top: 1px solid var(--line);
  }

  .mobile-menu-nav span {
    color: var(--muted);
    font: var(--text-sm) var(--mono);
    letter-spacing: .05em;
  }

  /* Current-page marker: a dot in the left margin plus the number badge
     matching the label's color instead of the usual dimmer --muted. */
  .mobile-menu-nav a.is-current {
    padding-left: 1.25rem;
  }

  .mobile-menu-nav a.is-current::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: .5rem;
    height: .5rem;
    transform: translateY(-50%);
    border-radius: 50%;
    background: currentColor;
  }

  .mobile-menu-nav a.is-current span {
    color: currentColor;
  }

  .mobile-menu-current {
    margin-top: 1.5rem;
  }

  .mobile-menu-current .working-module {
    margin-bottom: 1.5rem;
  }

  .mobile-menu-current .working-content {
    font-size: .6875rem;
  }

  .mobile-menu-listening .listening-head {
    margin-top: .25rem;
  }

  .mobile-menu-listening .listening-track {
    padding-top: .75rem;
  }

  .mobile-menu-listening .listening-track strong {
    font-size: .75rem;
  }

  .mobile-menu-listening .listening-track span {
    font-size: var(--text-xs);
  }

  .mobile-menu-listening .spectrogram-canvas {
    height: 3rem;
  }

  .mobile-menu-meta {
    display: flex;
    justify-content: space-between;
    margin-top: auto;
    color: var(--muted);
    font: var(--text-sm) var(--mono);
    text-transform: uppercase;
    letter-spacing: .05em;
  }

  .section {
    padding-inline: var(--page-pad);
  }

  /* Compact mobile header */
  .sidebar {
    position: relative;
    z-index: 50;
    width: 100%;
    min-width: 0;
    max-width: none;
    height: auto;
    padding: 1rem var(--page-pad) .875rem;
    border-right: 0;
    border-bottom: 0;
    background: transparent;
  }

  .sidebar-identity {
    display: none;
  }

  .sidebar-logo {
    font-size: .75rem;
  }

  .sidebar-location {
    font-size: var(--text-xs);
  }

  .sidebar-middle {
    display: none;
  }

  .listening-head {
    padding-bottom: .4375rem;
    font-size: var(--text-xs);
  }

  .listening-track {
    padding: .5rem 0 .625rem;
    gap: .1875rem;
  }

  .listening-track strong {
    font-size: .6875rem;
  }

  .listening-track span {
    font-size: var(--text-xs);
  }

  #spectrogram {
    height: 3.25rem;
  }

  .sidebar-bottom {
    display: none;
  }

  .sidebar-nav {
    flex-direction: row;
    flex-wrap: wrap;
    gap: .4375rem .9375rem;
    font-size: var(--text-sm);
  }

  .sidebar-clock {
    flex: 0 0 auto;
    font-size: var(--text-sm);
  }

  main {
    margin-left: 0;
  }

  /* Collapse toggle and its compact top bar are a desktop-only affordance —
     below this width the sidebar is already the compact mobile header (see
     the .sidebar rules above), so both stay out of the way entirely. */
  .sidebar-collapse-toggle,
  .sidebar-rail-mark,
  .sidebar-rail-clock,
  .sidebar-topbar-wrap {
    display: none;
  }

  /* About / hero: mobile uses the hero as a full-viewport composition.
     The portrait becomes the image field; typography sits over it rather than
     being stacked into a separate editorial sequence. Scoped to Home only —
     .sidebar is universal now (see templates/header.php), and this absolute
     float only makes sense over Home's own hero; on any other page it just
     floats over — and, on dark pages, opaquely covers — whatever content
     starts at the top of <main>. */
  body.home-page .sidebar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: auto;
  }

  .section--about {
    min-height: 100svh;
    padding-top: 0;
    padding-bottom: 0;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
    isolation: isolate;
    background: var(--fg);
  }

  .section--about::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: linear-gradient(180deg, rgba(23,23,20,.06) 18%, rgba(23,23,20,.18) 48%, rgba(23,23,20,.78) 100%), var(--hero-image);
    background-size: cover;
    background-position: center 32%;
    filter: grayscale(100%);
    transform: scale(1.01);
  }

  .section--about::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(23,23,20,.34) 0%, rgba(23,23,20,0) 62%);
  }

  .section--about .content {
    position: relative;
    z-index: 2;
    width: 100%;
    margin: 0;
    padding: 7rem 0 2rem;
    color: #fefcf9;
  }

  .section--about .kicker {
    color: rgba(254,252,249,.72);
  }

  .statement {
    max-width: 100%;
    margin: 1.5rem 0 0;
    font-size: clamp(2.55rem, 12.2vw, 4.5rem);
    line-height: .88;
    letter-spacing: -.075em;
    position: static;
    transform: none;
    /* Mobile already guarantees contrast with the gradient overlay on
       .section--about::after — the difference-blend trick from desktop
       isn't needed (and would fight that overlay), so it's reset here. */
    color: #fefcf9;
    mix-blend-mode: normal;
  }

  .statement .statement-muted {
    color: rgba(254,252,249,.62);
  }

  .about-portrait-wrap {
    display: none;
  }

  .about-detail {
    margin-top: 2rem;
  }

  .detail-meta {
    color: rgba(254,252,249,.72);
  }

  /* Work: eliminate the desktop-sized cards and make every project
     immediately scannable. */
  .section--archive {
    padding-top: 9vh;
    padding-bottom: 5vh;
  }

  .archive-intro {
    display: block;
  }

  .archive-intro h2,
  .gallery-head h2 {
    margin-top: 1.375rem;
    font-size: clamp(2.75rem, 12vw, 4.375rem);
    line-height: .86;
  }

  .archive-note {
    max-width: 16.875rem;
    margin-top: 1.75rem;
    font-size: .625rem;
  }

  .archive-list {
    margin-top: 4rem;
  }

  .archive-item {
    min-height: 0;
    padding: 1.0625rem 0 1.25rem;
    display: grid;
    grid-template-columns: 1.75rem minmax(0, 1fr) 1.125rem;
    grid-template-rows: auto auto;
    column-gap: .625rem;
    row-gap: .75rem;
    align-items: start;
  }

  .archive-item::before {
    display: none;
  }

  .archive-item:hover,
  .archive-item:focus-within {
    padding-inline: 0;
    color: #e9e9e4;
    background: var(--fg);
  }

  .archive-number {
    padding-top: .25rem;
    font-size: var(--text-sm);
  }

  .archive-title {
    font-size: clamp(2.8125rem, 13vw, 4.375rem);
    line-height: .78;
  }

  .archive-info {
    grid-column: 2 / 4;
    margin: 0;
  }

  .archive-info > span {
    display: block;
    font-size: var(--text-sm);
  }

  .archive-info small {
    max-width: 15.9375rem;
    margin-top: .5rem;
    font-size: .625rem;
    line-height: 1.45;
  }

  .archive-arrow {
    display: block;
    grid-column: 3;
    grid-row: 1;
    padding-top: .125rem;
    font-size: var(--text-body-lg);
  }

  /* Field Notes: mobile uses viewport-relative vertical sizing instead of a fixed card height. */
  .archive-item:hover .archive-title,
  .archive-item:hover .archive-arrow,
  .archive-item:focus-within .archive-title,
  .archive-item:focus-within .archive-arrow {
    color: #e9e9e4;
  }

  .archive-item:hover .archive-number,
  .archive-item:hover .archive-info > span,
  .archive-item:focus-within .archive-number,
  .archive-item:focus-within .archive-info > span {
    color: #aaa;
  }

  .archive-item:hover .archive-info small,
  .archive-item:focus-within .archive-info small {
    color: #ccc;
  }

  .section--field-notes {
    padding-top: 8vh;
    padding-bottom: 9vh;
  }

  .section--field-notes::before {
    left: calc(-1 * var(--page-pad));
    width: calc(100% + var(--page-pad));
  }

  .field-notes-head {
    display: block;
    margin-bottom: 2.375rem;
  }

  .field-notes-head h2 {
    margin-top: var(--space-2);
    font-size: clamp(2.8125rem, 12vw, 4.25rem);
    line-height: .86;
  }

  .field-notes-head > p {
    margin: 1.25rem 0 0;
    font-size: var(--text-sm);
  }

  .field-notes-layout {
    display: block;
    min-height: 0;
  }

  .field-note-feature {
    min-height: 45vh;
    padding: 1.5rem 1.25rem 1.625rem;
    border-right: 0;
    border-bottom: 1px solid rgba(255,255,255,.16);
  }

  .field-note-feature h3 {
    margin-bottom: 1rem;
    font-size: clamp(2.125rem, 9.2vw, 3.375rem);
    line-height: .9;
  }

  .field-note-feature p {
    max-width: 19.375rem;
    margin-bottom: 1.375rem;
    font-size: .75rem;
  }

  .field-note-list a {
    grid-template-columns: 1.625rem minmax(0, 1fr);
    column-gap: .75rem;
    padding: 1.125rem 1rem;
  }

  .field-note-list strong {
    font-size: var(--text-body);
    line-height: 1.2;
  }

  .field-note-list small {
    margin-top: var(--space-2);
    font-size: var(--text-xs);
  }

  /* Gallery: same 2-column mosaic as desktop, spacing just tightens further. */
  .section--gallery {
    padding-top: 5vh;
    padding-bottom: 10vh;
  }

  .gallery-head {
    display: block;
  }

  .editorial-grid {
    --gallery-gap: .625rem;
    margin-top: 3.25rem;
  }

  /* Closing: make the CTA feel like a destination, not another huge
     viewport-height gap. */
  .section--closing {
    min-height: 76svh;
    padding-top: 9vh;
    padding-bottom: 1.125rem;
  }

  .closing-title {
    margin-top: 9vh;
    font-size: clamp(3.625rem, 16vw, 5.75rem);
    line-height: .8;
  }

  .socials {
    margin-top: 8vh;
    gap: .625rem 1.375rem;
    font-size: var(--text-sm);
  }

  .section--closing footer {
    grid-template-columns: 1fr auto;
    gap: .5rem 1.125rem;
    margin-top: 9vh;
    font-size: var(--text-xs);
    line-height: 1.4;
  }

  .section--closing footer a {
    text-align: right;
  }
}

@media (max-width: 26.875rem) {
  .sidebar-location {
    display: none;
  }

  .sidebar-logo {
    font-size: .6875rem;
  }

  .sidebar-nav {
    gap: .375rem .75rem;
  }

  .statement {
    margin-top: 1.875rem;
    font-size: clamp(2.125rem, 10.8vw, 3.4375rem);
  }

  .archive-title {
    font-size: clamp(2.625rem, 13.5vw, 3.875rem);
  }

  .field-note-feature {
    min-height: 42vh;
  }

  .editorial-grid {
    --gallery-gap: .5rem;
  }
}

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

  .about-portrait-wrap {
    transform: translate3d(-50%, 0, 0);
  }

  .live-dot {
    animation: none;
  }

  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* Micro-interactions */
@media (hover: hover) and (pointer: fine) {
  .sidebar-logo,
  .sidebar-nav a,
  .text-link,
  .socials a,
  .field-note-feature a,
  .field-note-list a,
  .archive-item {
    will-change: transform;
  }

  .sidebar-logo {
    display: inline-flex;
    transition: transform .35s cubic-bezier(.2,.8,.2,1), letter-spacing .35s ease;
  }

  .sidebar-logo:hover {
    transform: translateX(.22rem);
    letter-spacing: -.02em;
  }

  .sidebar-nav a {
    display: inline-block;
    transition: opacity .25s ease, transform .35s cubic-bezier(.2,.8,.2,1);
  }

  .sidebar-nav a:hover {
    transform: translateX(.35rem);
  }

  .text-link {
    position: relative;
    text-decoration: none;
    border-bottom: 0;
  }

  .text-link::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -.08em;
    height: 1px;
    background: currentColor;
    transform: scaleX(1);
    transform-origin: right center;
    transition: transform .35s cubic-bezier(.2,.8,.2,1);
  }

  .text-link:hover::after {
    transform: scaleX(0);
    transform-origin: left center;
  }

  .archive-item {
    transition: color .35s ease, padding .45s cubic-bezier(.2,.8,.2,1), transform .45s cubic-bezier(.2,.8,.2,1);
  }

  .archive-item:hover {
    transform: translateX(.18rem);
  }

  .archive-title,
  .archive-arrow {
    transition: transform .45s cubic-bezier(.2,.8,.2,1), color .35s ease;
  }

  .archive-item:hover .archive-title {
    transform: translateX(.35rem);
  }

  .archive-item:hover .archive-arrow {
    transform: translate( .25rem, -.25rem) rotate(4deg);
  }

  .gallery-cta-arrow {
    transition: transform .45s cubic-bezier(.2,.8,.2,1);
  }

  .gallery-cta:hover .gallery-cta-arrow {
    transform: translate( .25rem, -.25rem) rotate(4deg);
  }

  .field-note-list a {
    transition: background .3s ease, transform .4s cubic-bezier(.2,.8,.2,1), padding-left .4s cubic-bezier(.2,.8,.2,1);
  }

  .field-note-list a:hover {
    transform: translateX(.25rem);
    padding-left: clamp(1.5rem, 2.35vw, 2.2rem);
  }

  .field-note-list strong {
    transition: transform .35s cubic-bezier(.2,.8,.2,1), letter-spacing .35s ease;
  }

  .field-note-list a:hover strong {
    letter-spacing: -.01em;
  }

  .field-note-feature a {
    display: inline-block;
    transition: transform .35s cubic-bezier(.2,.8,.2,1), opacity .25s ease;
  }

  .field-note-feature a:hover {
    transform: translateX(.3rem);
  }

  .socials a {
    display: inline-block;
    transition: transform .35s cubic-bezier(.2,.8,.2,1), opacity .25s ease;
  }

  .socials a:hover {
    transform: translateY(-.2rem);
  }

  .socials span {
    display: inline-block;
    transition: transform .35s cubic-bezier(.2,.8,.2,1);
  }

  .socials a:hover span {
    transform: translate(.2rem, -.2rem);
  }

  .closing-title span {
    transition: transform .6s cubic-bezier(.2,.8,.2,1);
  }

  .closing-title:hover span:first-child {
    transform: translateX(.35rem);
  }

  .closing-title:hover span:last-child {
    transform: translateX(-.35rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar-logo,
  .sidebar-nav a,
  .text-link,
  .archive-item,
  .archive-title,
  .archive-arrow,
  .gallery-cta,
  .gallery-cta-arrow,
  .field-note-list a,
  .field-note-list strong,
  .field-note-feature a,
  .socials a,
  .socials span,
  .closing-title span {
    transition: none !important;
    transform: none !important;
  }

  .sidebar-mark {
    animation: none !important;
  }
}

@media (max-width: 760px) {
  .section--statement {
    padding-top: 5rem;
    padding-bottom: 5rem;
  }

  .statement-block {
    font-size: clamp(2.15rem, 9vw, 3.4rem);
    line-height: 1;
    letter-spacing: -.055em;
  }
}

/* CMS image hydration: preserves each image's original aspect ratio. */
.piece-media img,
.piece-media video {
  display: block;
  width: 100%;
  height: auto;
}

/* The closing section is rendered by the shared footer outside <main>, on
   every page — needs the same sidebar-width margin as main itself. */
.section--closing {
  margin-left: var(--sidebar-width);
}

@media (max-width: 50rem) {
  .section--closing {
    margin-left: 0;
  }
}

/* CMS fallback pages outside the supplied editorial mockups. site/ has no
   projeto.php/galeria.php (see site/CONTEXT.md — their absence here is
   intentional), so this only ever needs to cover the page types that
   actually exist: Pages (.content-page) and the 404 (.error-page). */
.cms-content-shell,
.content-page,
.error-page {
  width: min(100%, var(--content-width));
  margin-inline: auto;
}
.cms-content-shell {
  min-height: 100svh;
  padding: clamp(5rem, 10vh, 8rem) var(--page-pad);
}
.cms-content-shell h1,
.content-page h1,
.error-page h1 {
  margin: 1rem 0 0;
  max-width: 13ch;
  font-family: var(--display);
  font-size: clamp(3rem, 7vw, 7rem);
  line-height: .88;
  letter-spacing: -.075em;
  font-weight: 400;
}
.cms-content-shell p,
.content-page p,
.error-page p {
  max-width: 54rem;
  line-height: 1.7;
}

.sidebar-logo img {
  display: block;
  width: auto;
  max-width: 10rem;
  max-height: 2rem;
  object-fit: contain;
}
