/* ── DESIGN ── */

/* ── HEADER TWO-COLUMN LAYOUT ── */

.art-header-layout {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 2.5rem;
  margin-top: 2rem;
  margin-bottom: 1.5rem;
  align-items: start;
}

.art-header-text {
  display: flex;
  flex-direction: column;
}


.art-header-bio-area {
  display: flex;
  flex-direction: column;
  gap: 0.85em;
}

/* TYPE ROLES: long-form prose in --font-prose (IBM Plex Sans); DM Sans stays
   for display titles; DM Mono stays for nav, labels, captions, metadata, and
   terminal moments (ghost trees, cram text). */
.art-header-bio {
  font-family: var(--font-prose);
  font-weight: 400;
  letter-spacing: 0.01em;
  font-size: 0.84rem;
  line-height: 1.75;
  color: var(--cream);
  opacity: 0.6;
  margin: 0;
}

.art-header-social {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.55rem;
  padding-top: 0.6em;
}

/* ── PHOTO STRIP GRID ── */

.art-photo-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.45rem;
}

.art-photo-tile {
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid rgba(var(--accent-rgb),0.2);
}

.art-photo-tile img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.art-photo-tile:hover img {
  transform: scale(1.05);
}

/* ── FOLDER HEADER + FILTER ── */
.art-folder-header {
  display: flex;
  align-items: baseline;
  gap: 2rem;
  margin-top: 2rem;
  padding-bottom: 1.4rem;
  margin-bottom: 0.2rem;
  flex-wrap: wrap;
}

.art-filter-row {
  display: flex;
  gap: 0.1rem;
  align-items: baseline;
}

.art-filter-btn {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: lowercase;
  color: rgba(var(--cream-rgb),0.28);
  background: none;
  border: none;
  padding: 0.2rem 0.55rem;
  cursor: pointer;
  transition: color 0.15s;
}

.art-filter-btn:hover {
  color: rgba(var(--cream-rgb),0.65);
}

.art-filter-btn--active {
  color: var(--accent);
}

/* hidden during filter */
.post--hidden {
  display: none;
}

/* bottom border on last visible post after filtering */
.post--last-visible {
  border-bottom: 1px solid rgba(var(--cream-rgb),0.12);
}

/* fix background so it doesn't extend the scroll area — same as about/music/research */
#page-design .subpage-bg {
  position: fixed;
}

/* fill available space so footer always sits flush below content */
.art-post-list {
  flex: 1 0 auto;
}

/* ── ENTRY REVEAL SEQUENCE ── */

.art-reveal--hidden {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* header and bg-img have their own transitions so they fade in when class is removed */
#page-design .art-header-layout {
  transition: opacity 1.2s ease;
}

#page-design .subpage-bg-img {
  transition: opacity 1.8s ease;
}

.post {
  padding: 2rem 0;
  border-top: 1px solid rgba(var(--cream-rgb),0.12);
  transition: opacity 0.5s ease;
}

.post:last-child { border-bottom: 1px solid rgba(var(--cream-rgb),0.12); }

.post-status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 0.7rem;
}

.post-status::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* live = semantic green; the only non-palette color (warm cream/tan/brown can't express it) */
.post-status--live {
  --status-live: #7a9e6e;
  color: var(--status-live);
}
.post-status--live::before {
  background: var(--status-live);
  animation: status-pulse 2.6s ease-in-out infinite;
}

/* live = breathing — slow brightness pulse on the status dot only */
@keyframes status-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}

@media (prefers-reduced-motion: reduce) {
  .post-status--live::before { animation: none; }
  /* case-study reveals are force-shown at init under reduced-motion — make the
     transition instant so content snaps in rather than fading/sliding. */
  .reveal { transition: none; }
}

.post-status--dev {
  color: var(--warm-mid);
}
.post-status--dev::before {
  background: var(--warm-mid);
  opacity: 0.55;
}

/* soon = pre-release, awaiting launch confirmation; accent dot, no pulse */
.post-status--soon {
  color: var(--accent);
}
.post-status--soon::before {
  background: var(--accent);
  opacity: 0.7;
}

/* GitHub repo affordance in a teaser title row. <a> when live; <span class="post-gh--soon"> while the repo is still private. */
.post-gh {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--warm-mid);
  line-height: 0;
}
.post-gh svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}
a.post-gh {
  text-decoration: none;
  transition: color 0.2s;
}
a.post-gh:hover { color: var(--cream); }
.post-gh--soon {
  opacity: 0.38;
  cursor: default;
}

.post-title {
  font-family: 'DM Sans', sans-serif;
  font-size: clamp(1.4rem, 3vw, 2rem);
  font-weight: 300;
  letter-spacing: 0.04em;
  margin-bottom: 0.9rem;
  color: var(--cream);
}

.post-title-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 0.9rem;
}

.post-title-row .post-title {
  margin-bottom: 0;
}

.post-title-icon {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  border-radius: 12px;
  object-fit: cover;
  display: block;
}

.post-excerpt {
  font-family: var(--font-prose);
  font-weight: 300;
  letter-spacing: 0.01em;
  font-size: 1rem;
  line-height: 1.8;
  color: rgba(var(--cream-rgb),0.7);
  max-width: 980px;
}

.post-read-more {
  display: inline-block;
  /* <button> doesn't inherit font-family (UA sans) — set DM Mono explicitly so
     it matches its mono siblings (.post-action) in the row, and so the hover
     scramble runs in a fixed-width face (no per-frame reflow / jitter). */
  font-family: 'DM Mono', monospace;
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  /* 0.5rem margin + 0.3rem padding ≈ the old 0.8rem top gap, but the padding
     now enlarges the hover/click target beyond the ~12px text band. */
  margin-top: 0.5rem;
  padding: 0.3rem 0;
  text-decoration: none;
  /* Front-loaded (ease-out) + short so the feedback registers the instant the
     cursor lands, instead of a slow-start ease that reads as activation lag.
     Brighten toward cream — a legible signal, unlike the old subtle dim. */
  transition: color 0.13s ease-out;
  background: none;
  border: none;
  cursor: pointer;
}

.post-read-more:hover { color: var(--cream); }

/* ── TEASER ACTION ROW ──
   External links (Gumroad/GitHub) live in a row under the excerpt, beside
   "Read more" — not as bare icons next to the title. Title = identity,
   actions = navigation. */
.post-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.6rem;
  margin-top: 0.8rem;
}

.post-actions .post-read-more {
  /* Negative margin cancels the new vertical padding so the action row height
     is unchanged (no reflow of the Gumroad/GitHub items) while the enlarged
     hover target is kept. */
  margin: -0.3rem 0;
}

.post-action {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--warm-mid);
  text-decoration: none;
  transition: color 0.13s ease-out;
}

.post-action svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
  flex-shrink: 0;
}

/* Bio-block social links carry brand marks (Spotify/Bandcamp/LinkedIn/etc.) —
   give them a touch more presence than the teaser-row action icons. */
.beats-bio-social .post-action svg,
.art-header-social .post-action svg,
.asm-header-social .post-action svg {
  width: 18px;
  height: 18px;
}

.post-action:hover { color: var(--cream); }

.post-action--soon {
  opacity: 0.38;
  cursor: default;
}

/* ── BEAT CRATE SUBPAGE ── */

/* Per-case-study accent (light material differentiation): the shared .bc-*
   chassis stays, but section labels, thread, dots, and marginalia take a
   product-tinted accent. Frame treatment (--frame-edge) is house-wide and
   deliberately NOT overridden. Fallback = house tan. */
#page-beatcrate {
  --cs-accent: #d49a56;            /* crate amber — warmer, toward cardboard/vinyl */
  --cs-accent-rgb: 212, 154, 86;
}
#page-surfacer {
  --cs-accent: #9ab0bc;            /* OS steel — cool desaturated workspace tone */
  --cs-accent-rgb: 154, 176, 188;
}
#page-annum {
  --cs-accent: #e79228;            /* candle amber — derived from the app icon's orange */
  --cs-accent-rgb: 231, 146, 40;
}

.bc-page,
.bc-header {
  padding: 2.4rem 3rem 4rem;
  max-width: none;
}

/* #11: .reveal-right rests at translateX(28px) until it animates in. On narrow
   viewports that 28px exceeds the page padding and pushes content ~6px past the
   viewport (faint horizontal jiggle). Clip horizontal overflow on the case-study
   scroll containers — the slide-in is never meant to be horizontally scrollable. */
#page-beatcrate,
#page-surfacer,
#page-annum {
  overflow-x: hidden;
}

/* Status badge + GitHub affordance share a top row in the case-study header */
.bc-header-top {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-bottom: 0.7rem;
}
.bc-header-top .post-status {
  margin-bottom: 0;
}

.bc-title {
  font-family: 'DM Sans', sans-serif;
  font-size: clamp(3rem, 7vw, 6rem);
  font-weight: 300;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--cream);
  margin-bottom: 1.2rem;
}

/* Title row: product icon beside the case-study name (larger than the teaser's 72px) */
.bc-title-row {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-bottom: 1.2rem;
}
.bc-title-row .bc-title {
  margin-bottom: 0;
}
.bc-title-icon {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  border-radius: 16px;
  object-fit: cover;
  display: block;
}

.bc-lede {
  font-family: var(--font-prose);
  font-weight: 300;
  letter-spacing: 0.01em;
  font-size: 1rem;
  line-height: 1.7;
  color: rgba(var(--cream-rgb),0.65);
}

/* THREAD */
.bc-thread-wrap {
  position: relative;
  padding-left: 2px;
  counter-reset: bc-sec;
}

.bc-section { counter-increment: bc-sec; }

/* section index numeral — "01 / " before each label, dimmer than the label */
.bc-label::before {
  content: counter(bc-sec, decimal-leading-zero) " / ";
  color: rgba(var(--cs-accent-rgb, 196, 168, 130), 0.5);
}

.bc-thread {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 0;
  background: rgba(var(--cs-accent-rgb, 196, 168, 130), 0.25);
  transition: height 0.1s linear;
}

.bc-section {
  position: relative;
  padding: 4rem 3rem;
  border-bottom: 1px solid rgba(var(--cream-rgb),0.06);
  overflow: visible;
}

.bc-section:last-child {
  border-bottom: none;
  padding-bottom: 2rem;
}

.bc-thread-dot {
  position: absolute;
  left: -4px;
  top: 4.4rem;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink);
  border: 1px solid rgba(var(--cs-accent-rgb, 196, 168, 130), 0.5);
  transition: background 0.3s, border-color 0.3s;
}

.bc-section.in-view .bc-thread-dot {
  background: var(--cs-accent, var(--accent));
  border-color: var(--cs-accent, var(--accent));
}

/* ROWS */
.bc-row {
  display: grid;
  gap: 3.5rem;
  align-items: center;
}

.bc-row-text-left {
  grid-template-columns: 1fr 1.4fr;
}

.bc-row-media-left {
  grid-template-columns: 1.4fr 1fr;
}

.bc-label {
  display: block;
  font-size: 1.1rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cs-accent, var(--accent));
  margin-bottom: 1.1rem;
  /* now an <h2> (section heading under the case-study <h1>); neutralize the UA
     heading margin-top + bold so it renders exactly as the old <span> did. */
  margin-top: 0;
  font-weight: inherit;
}

.bc-col-text p {
  font-family: var(--font-prose);
  font-weight: 300;
  letter-spacing: 0.01em;
  font-size: 1rem;
  line-height: 1.85;
  color: rgba(var(--cream-rgb),0.72);
  margin-bottom: 0.9rem;
}

.bc-col-text p:last-child { margin-bottom: 0; }
.bc-col-text em { color: rgba(var(--cream-rgb),0.9); font-style: italic; }

.bc-img {
  width: 100%;
  display: block;
  border-radius: 6px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
  cursor: zoom-in;
  transition: opacity 0.25s, transform 0.25s;
}

.bc-img:hover {
  opacity: 0.85;
  transform: translateY(-2px);
}

.bc-img-caption {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--warm-mid);
  margin-top: 0.5rem;
  opacity: 0.7;
}

/* SCROLL REVEAL */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.65s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.65s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.reveal-right {
  transform: translateX(28px);
}

.reveal-left {
  transform: translateX(-28px);
}

.reveal.visible {
  opacity: 1;
  transform: translate(0, 0);
}


/* ── PROBLEM SECTION ── */
.bc-section-problem {
  position: relative;
  overflow: hidden;
  min-height: 420px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.bc-problem-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.12;
  pointer-events: none;
}

.bc-problem-tree {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 2rem 3rem;
}

.bc-problem-tree pre {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  line-height: 1.7;
  color: var(--cream);
  opacity: 0.07;
  white-space: pre;
  letter-spacing: 0.02em;
  margin: 0;
  text-align: left;
}

/* Surfacer §1 variant — single stream-of-consciousness wall of text
   instead of the hierarchical file tree BeatCrate uses. Wraps as a
   ragged-right column to read as one crammed note, not a structure. */
.bc-cram-text {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  line-height: 1.55;
  color: var(--cream);
  opacity: 0.07;
  letter-spacing: 0.02em;
  max-width: 42ch;
  text-align: left;
  word-break: break-word;
}

/* Annum §1 variant — the deleted feed. Wrapper opacity is bumped so the
   surviving birthday lines read; junk is struck through and dimmed back
   toward the original ghost level so only the salvaged signal stands out.
   No hue shift — contrast is opacity + strikethrough only. */
.bc-cram-text--feed {
  opacity: 0.14;
}
.bc-cram-text--feed .an-junk {
  text-decoration: line-through;
  opacity: 0.4;
}
.bc-cram-text--feed .an-keep {
  opacity: 1;
}

.bc-problem-content {
  position: relative;
  z-index: 1;
  max-width: 520px;
  padding: 4rem 0 2rem;
}

.bc-problem-single {
  position: relative;
  z-index: 1;
  max-width: 60%;
  margin: 0 auto;
  padding-bottom: 3rem;
}

.bc-stacked-pair {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  width: 100%;
}

.bc-stacked-pair img {
  width: 100%;
  display: block;
  border-radius: 6px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
}

/* Layered plugin composite — dimmed/blurred background context shot
   with a sharp foreground close-up floating above it. Used in BeatCrate §3
   to show the Max for Live device both in Ableton and as a focused window. */
.bc-plugin-layered {
  position: relative;
  width: 100%;
  aspect-ratio: 3024 / 1964;
  border-radius: 6px;
  overflow: visible;
}

/* Scope under .bc-plugin-layered to override .bc-stacked-pair img */
.bc-plugin-layered .bc-plugin-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 6px;
  box-shadow: 0 8px 40px rgba(0,0,0,0.55), 0 0 0 1px rgba(var(--accent-rgb),0.2);
  opacity: 0.42;
  filter: blur(1.2px) saturate(0.85);
  cursor: zoom-in;
  transition: opacity 0.25s, filter 0.25s;
}

.bc-plugin-layered .bc-plugin-bg:hover {
  opacity: 0.6;
  filter: blur(0.5px) saturate(1);
}

.bc-plugin-layered .bc-plugin-fg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44%;
  height: auto;
  display: block;
  border-radius: 6px;
  box-shadow:
    0 28px 80px rgba(0,0,0,0.9),
    0 8px 24px rgba(0,0,0,0.55),
    0 0 0 1.5px rgba(var(--accent-rgb),0.45);
  cursor: zoom-in;
  transition: transform 0.25s, opacity 0.25s;
}

.bc-plugin-layered .bc-plugin-fg:hover {
  opacity: 0.94;
  transform: translate(-50%, calc(-50% - 2px));
}

/* ── FINALE SECTION ── */
.bc-section-finale {
  position: relative;
  overflow: visible;
  padding-top: 2rem;
  padding-bottom: 0;
}

/* ── BEAT CRATE CASE STUDY ── */
.post-teaser-layout {
  display: flex;
  gap: 2.4rem;
  align-items: center;
}

.post-teaser-text {
  flex: 0 0 auto;
  width: clamp(220px, 30vw, 380px);
}

.post-teaser-images {
  flex: 1;
  min-width: 0;
}

.post-teaser-hover {
  position: relative;
  overflow: hidden;
  border-radius: 10px;
  cursor: pointer;
  box-shadow: var(--frame-shadow), var(--frame-edge);
}

.post-teaser-hover img {
  width: 100%;
  display: block;
}

/* After image — always visible underneath */
.post-teaser-after {
  display: block;
}

/* ── RESIDUE TEASER ── */
.residue-teaser-stack {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.residue-teaser-hero {
  width: 100%;
  display: block;
  border-radius: 10px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-drag: none;
}

.residue-teaser-sub {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.4rem;
}

.residue-teaser-sub img {
  width: 100%;
  display: block;
  border-radius: 10px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
  object-fit: contain;
}

.residue-img-wrap {
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  box-shadow: var(--frame-shadow), var(--frame-edge);
}

.residue-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* GLASS teaser — layered composite (mirrors .bc-plugin-layered): the full
   Ableton session sits dimmed/blurred behind, with the sharp GLASS device
   banner floating in front, nudged below center toward where it docks. */
.glass-teaser-layered {
  position: relative;
  width: 100%;
  aspect-ratio: 1800 / 1169;
  border-radius: 10px;
  overflow: visible;
}
.glass-teaser-layered .glass-teaser-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 10px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
  opacity: 0.4;
  filter: blur(1.2px) saturate(0.85);
}
.glass-teaser-layered .glass-teaser-fg {
  position: absolute;
  top: 56%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 86%;
  height: auto;
  display: block;
  border-radius: 8px;
  box-shadow:
    0 28px 80px rgba(0,0,0,0.9),
    0 8px 24px rgba(0,0,0,0.55),
    0 0 0 1.5px rgba(var(--accent-rgb),0.45);
}

.residue-teaser-sub--1col { grid-template-columns: 1fr; }
.residue-teaser-sub--2col { grid-template-columns: 1fr 1fr; gap: 0.9rem; }

.post-teaser-img {
  width: 100%;
  display: block;
  border-radius: 10px;
  box-shadow: var(--frame-shadow), var(--frame-edge);
}

/* ── MARGINALIA — train-of-thought sidenotes ──
   A note lives inside the .bc-col-text it annotates, immediately after the
   <p> containing its anchor. Image column (.bc-col-media) is untouched and
   keeps its full width — the row stays a normal 2-col bc-row.
   In-body anchor: <span class="bc-note-anchor" data-note="id" data-marker="¹">…</span>.
   Note:           <aside class="bc-note" data-note="id">…</aside> */

.bc-note {
  display: block;
  font-family: var(--font-prose);
  font-weight: 400;
  letter-spacing: 0.01em;
  font-size: 0.85rem;
  line-height: 1.7;
  color: rgba(var(--cream-rgb),0.62);
  margin-top: 1.8rem;
  padding: 0.1rem 0 0.1rem 1rem;
  border-left: 1px solid rgba(var(--cs-accent-rgb, 196, 168, 130), 0.32);
}

.bc-note-title {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cs-accent, var(--accent));
  margin-bottom: 0.55rem;
  font-weight: 500;
}

.bc-note p {
  margin: 0 0 0.65rem 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

.bc-note p:last-child { margin-bottom: 0; }

.bc-note a {
  color: rgba(var(--cream-rgb),0.82);
  text-decoration: none;
  border-bottom: 1px solid rgba(var(--cs-accent-rgb, 196, 168, 130), 0.4);
  transition: color 0.25s, border-color 0.25s;
}

.bc-note a:hover {
  color: var(--cs-accent, var(--accent));
  border-bottom-color: var(--cs-accent, var(--accent));
}

.bc-note-anchor {
  border-bottom: 1px dashed rgba(var(--cs-accent-rgb, 196, 168, 130), 0.45);
  transition: border-color 0.25s, color 0.25s;
}

.bc-note-anchor:hover {
  border-bottom-color: var(--cs-accent, var(--accent));
  color: rgba(var(--cream-rgb),0.95);
}

.bc-note-anchor::after {
  content: attr(data-marker);
  font-size: 0.68em;
  vertical-align: super;
  margin-left: 0.16em;
  color: var(--cs-accent, var(--accent));
  font-weight: 500;
  font-family: var(--font-prose);
  letter-spacing: 0;
}

/* ── RESPONSIVE ── */
@media (max-width: 768px) {
  /* Beat Crate — remove bc-page's own horizontal padding; subpage padding handles the margin */
  .bc-page,
  .bc-header {
    padding-left: 0;
    padding-right: 0;
  }

  .bc-section {
    padding: 2.5rem 0;
  }

  /* Collapse all two-column rows to single column */
  .bc-row-text-left,
  .bc-row-media-left {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  /* Marginalia: note rides along with its parent .bc-col-text when the
     row collapses to single column. Tighten the top margin slightly so
     it doesn't feel detached from its paragraph on narrow screens. */
  .bc-note {
    margin-top: 1.2rem;
  }

  /* Layered plugin composite — on narrow screens the absolute-positioned
     foreground close-up gets cramped. Switch to a simple stacked layout. */
  .bc-plugin-layered {
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
  }

  .bc-plugin-bg,
  .bc-plugin-fg {
    position: static;
    width: 100%;
    height: auto;
    transform: none;
    opacity: 1;
    filter: none;
  }

  .bc-plugin-fg:hover {
    transform: none;
  }

  /* Hide decorative thread — its absolute positioning doesn't translate well to mobile */
  .bc-thread,
  .bc-thread-dot {
    display: none;
  }

  /* Hide purely decorative file-tree pre text */
  .bc-problem-tree {
    display: none;
  }


  .bc-section-problem {
    min-height: 0;
  }

  .bc-problem-content {
    padding: 2rem 0;
  }

  /* Design page — Beat Crate post teaser */
  .post-teaser-layout {
    flex-direction: column;
    gap: 1.5rem;
  }

  .post-teaser-text {
    width: 100%;
  }
}

@media (max-width: 860px) {
  .art-header-layout { grid-template-columns: 1fr; gap: 1.5rem; }
}

@media (max-width: 520px) {
  .bc-title { font-size: clamp(2rem, 7vw, 6rem); }
  .bc-title-icon { width: 64px; height: 64px; border-radius: 12px; }
  .residue-teaser-sub { grid-template-columns: 1fr 1fr; }
  .art-photo-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── CLS img dims: keep width-scaled images at natural aspect ──
   The width/height attributes (added 2026-06-21 for layout-shift reservation)
   map to presentational height *hints*. These classes scale by width with an
   implicit auto height, so without an explicit CSS height the hint forces a
   literal pixel height and distorts the image. height:auto overrides the hint
   while the attrs still feed the browser's aspect-ratio CLS reservation. */
.bc-img,
.post-teaser-img,
.post-teaser-hover img,
.residue-teaser-hero,
.bc-stacked-pair img,
.residue-teaser-sub > img {
  height: auto;
}
