/* ---------------------------------------------------------------------------
   sebas-arcade v3 · animated bookends, readable middle.
   Warm Ground, lifted from src/styles/tokens.css.
--------------------------------------------------------------------------- */
:root {
  --sc-canvas:     #F4EEE4;
  --sc-surface:    #FBF7F0;
  --sc-ink:        #2E2620;
  /* Warm Ground documents this as #8A6F55, which measures 4.06:1 on the page
     canvas and 4.38:1 on the card surface. Both fail AA for the 18px body copy
     it carries, and the tools card's tinted panel took it to 3.74:1. Darkened
     one step to the value the eyebrow was already using as a one-off, so the
     page now has a single muted colour instead of two. Worst case 4.59:1. */
  --sc-ink-soft:   #7C6146;
  --sc-accent:     #C0603E;
  /* Solid buttons only. #C0603E under #FBF7F0 measures 3.95:1, which fails
     AA for 14px/500 text. This is the primary call to action, so it is the
     one place the palette bends. Same terracotta family, 5.30:1. */
  --sc-accent-strong: #A84B2C;
  --sc-accent-ink: #FBF7F0;

  --sc-font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --sc-font-text:    'Inter', system-ui, -apple-system, sans-serif;
  --sc-font-mono:    'Space Mono', ui-monospace, monospace;

}

body { background: var(--sc-canvas); }

/* ================================================================= plates ==
   Stacked, each faded independently, none ever faded back out: the topmost
   visible one covers the ones beneath. Fading a lower plate out while an upper
   one fades in leaves both semi-transparent and composites a double exposure. */
.plates, .actorlayer { position: fixed; inset: 0; pointer-events: none; }
.plates { z-index: 0; }
.actorlayer { z-index: 1; }         /* above the plates, below the paper */
.actorlayer svg { width: 100%; height: 100%; display: block; }

.plate {
  position: absolute; inset: 0; opacity: 0;
  background-size: cover; background-position: center center; background-repeat: no-repeat;
  will-change: opacity;
}
.plate--dawn     { background-image: url('assets/dawn-m.webp'); opacity: 1; }
.plate--day      { background-image: url('assets/day-m.webp'); }
@media (min-width: 861px) {
  .plate--dawn     { background-image: url('assets/dawn.webp'); }
  .plate--day      { background-image: url('assets/day.webp'); }
      }
/* A scrim only in the bands the copy sits in, never a full-frame wash. */
.plates__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--sc-canvas) 72%, transparent) 0%,
    transparent 30%, transparent 64%,
    color-mix(in oklab, var(--sc-canvas) 58%, transparent) 100%);
}
#claude { image-rendering: pixelated; filter: drop-shadow(0 4px 7px rgba(60, 40, 25, .3)); }
.ball { fill: none; stroke: var(--sc-accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ================================================================= chrome == */
.chrome {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: center; gap: clamp(0.75rem, 2.5vw, 2rem);
  padding: var(--sc-3) var(--sc-gutter);
  font-family: var(--sc-font-text); font-size: var(--sc-t-xs);
  /* Frozen light. It used to inherit --sc-canvas and --sc-ink, which invert at
     the same rate through the same midpoint, so the nav went to 1.06:1 and
     disappeared for ~76px of scroll. A fixed bar reads fine as a light band
     over a dark photograph and never crosses its own text. */
  background: color-mix(in oklab, #F4EEE4 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(46, 38, 32, 0.12);
}
.chrome__mark {
  font-family: var(--sc-font-display); font-size: var(--sc-t-sm); font-weight: 500;
  color: #2E2620; text-decoration: none; white-space: nowrap;
}
.chrome__mark span { color: #C0603E; }
.chrome__route { display: flex; gap: var(--sc-4); flex: 1 1 auto; }
.chrome__route a {
  /* Same darkening as --sc-ink-soft. Uppercase 12px mono on the frozen light
     bar was 4.06:1, and the nav is the one thing on the page that is always
     on screen. Hardcoded, not tokenised: the bar is deliberately frozen and
     must not follow the palette anywhere. */
  color: #7C6146; text-decoration: none;
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
}
.chrome__route a:hover { color: #2E2620; }
.chrome__cta {
  color: var(--sc-accent-ink); background: var(--sc-accent-strong);
  padding: var(--sc-2) var(--sc-4); border-radius: 999px;
  text-decoration: none; white-space: nowrap; font-weight: 500;
}
.chrome__lang { display: flex; gap: var(--sc-2); color: #7C6146; }
.chrome__lang a { color: inherit; text-decoration: none; }
.chrome__lang a.is-active { color: #2E2620; }
.chrome__lang i { font-style: normal; opacity: .4; }
:is(a, button, input, textarea):focus-visible {
  outline: 2px solid var(--sc-accent); outline-offset: 2px;
}

/* ================================================================ opening == */
.act { position: relative; z-index: 1; }
/* NO position on the stage. .sc-stage is position:sticky and overriding it
   silently unpins the act. */
.open { display: grid; align-content: center; padding-inline: var(--sc-gutter); }
/* The hero scrim lives in the PLATE layer, not on the act. On the act it sat
   above the actor layer and washed the character out to a ghost. Down here the
   order is: plates, scrim, characters, copy. */
.plates__hero {
  position: absolute; inset: 0; opacity: 0;
  background: linear-gradient(100deg,
    color-mix(in oklab, var(--sc-canvas) 90%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 72%, transparent) 32%,
    transparent 58%);
}
.open__copy { position: relative; max-width: min(44rem, 84vw); }
.open__copy > * + * { margin-top: var(--sc-4); }
.eyebrow, .open__badge {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  /* 12px mono over the illustration. This used to carry its own darker brown
     because the old --sc-ink-soft measured 4.06:1 here; the token is now that
     value, so the one-off is gone. */
  color: var(--sc-ink-soft);
}
.open h1 em { font-style: italic; color: var(--sc-accent); }

.btn {
  display: inline-block; cursor: pointer; border: 0;
  font-family: var(--sc-font-text); font-size: var(--sc-t-sm); font-weight: 500;
  color: var(--sc-accent-ink); background: var(--sc-accent-strong);
  padding: var(--sc-3) var(--sc-6); border-radius: 999px; text-decoration: none;
  transition: background-color .3s ease;
}
.btn:hover { background: color-mix(in oklab, var(--sc-accent-strong) 88%, #000); }
.btn--quiet {
  background: transparent; color: var(--sc-ink);
  border: 1px solid var(--sc-hairline-strong);
}
.btn--quiet:hover { background: color-mix(in oklab, var(--sc-ink) 6%, transparent); }

/* ================================================================== paper ==
   The readable middle. Opaque, so the fixed plates behind it are simply not
   there while you are reading. This is an ordinary website. */
.paper {
  position: relative; z-index: 2;
  background: var(--sc-canvas);
  padding-block: clamp(4rem, 9vw, 8rem);
}
.doc__wrap {
  max-width: 64rem; margin-inline: auto; padding-inline: var(--sc-gutter);
}
.doc { padding-block: clamp(2.5rem, 6vw, 5rem); }
.doc__head { max-width: 46rem; margin-bottom: var(--sc-6); }
.doc__head > * + * { margin-top: var(--sc-3); }
.doc__action { margin-top: var(--sc-6); }
.rule {
  height: 1px; border: 0; background: var(--sc-hairline);
  max-width: calc(64rem - 2 * var(--sc-gutter));
  margin-inline: auto;
}
.paper p { font-size: var(--sc-t-base); line-height: var(--sc-leading-body); max-width: 62ch; }
.soft { color: var(--sc-ink-soft); }
/* The glyph stands in for the word "heart", so it is content, not decoration,
   and owes 4.5:1. --sc-accent is 3.65:1 on paper. */
.heart { color: var(--sc-accent-strong); }

/* --- intro: text leads, portrait supports ------------------------------- */
.doc__wrap--intro {
  display: grid; grid-template-columns: minmax(0, 1fr) 15rem;
  gap: clamp(2rem, 5vw, 4rem); align-items: start;
}
.intro__text > * + * { margin-top: var(--sc-4); }
.intro__text .sc-lede { font-size: var(--sc-t-lg); }
.intro__portrait { margin: 0; }
.intro__portrait img {
  width: 100%; height: auto; display: block; border-radius: 14px;
  border: 1px solid var(--sc-hairline-strong);
}
.intro__portrait figcaption {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  color: var(--sc-ink-soft); margin-top: var(--sc-2);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
}

/* --- lists ---------------------------------------------------------------- */
.list { list-style: none; margin: 0; padding: 0; }
.list li { border-top: 1px solid var(--sc-hairline); }
.list li:last-child { border-bottom: 1px solid var(--sc-hairline); }
.list a, .list--plain li {
  display: grid; grid-template-columns: 7rem minmax(0, 1fr) auto;
  gap: var(--sc-4); align-items: baseline;
  padding: var(--sc-4) 0; text-decoration: none; color: var(--sc-ink);
}
.list--plain li { grid-template-columns: minmax(0, 1fr) auto; }
.list a:hover { color: var(--sc-accent); }
.list__kicker {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; color: var(--sc-ink-soft);
}
.list__title { font-family: var(--sc-font-display); font-size: var(--sc-t-lg); font-weight: 500; }
.list__meta { font-family: var(--sc-font-mono); font-size: var(--sc-t-xs); color: var(--sc-ink-soft); }

/* --- talks: a grid, not a rail -------------------------------------------- */
.grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.card img {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: 12px; display: block; margin-bottom: var(--sc-3);
}
.card h3 {
  font-family: var(--sc-font-display); font-size: var(--sc-t-lg);
  font-weight: 500; margin: 0 0 var(--sc-2);
}
.card p { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); margin: 0; }

/* ================================================================== close == */
.close { display: grid; align-content: center; justify-items: center; padding-inline: var(--sc-gutter); }
.close__panel {
  /* Centred with margins, NOT with transform: the engine writes
     element.style.transform on every cued element each frame, which silently
     destroyed a translate(-50%) and put this 156px off the right edge of a
     phone. Anything carrying data-sc-cue must leave transform alone. */
  position: absolute;
  left: var(--sc-gutter); right: var(--sc-gutter);
  margin-inline: auto;
  max-width: min(44rem, 100%);
  text-align: center;
  bottom: 8vh;
  background: var(--sc-surface);
  border: 1px solid var(--sc-hairline-strong);
  border-radius: 20px;
  padding: clamp(1.1rem, 2.4vw, 1.9rem);
  color: var(--sc-ink);
  box-shadow: 0 10px 50px -18px rgba(46, 38, 32, .28);
}
.close__panel .form { margin-top: var(--sc-4); }
.close__panel .sc-display { font-size: var(--sc-t-xl); }
.close__panel > * + * { margin-top: var(--sc-3); }
.close__panel p { color: var(--sc-ink-soft); margin-inline: auto; }
.form { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sc-3); text-align: left; }
.form__wide { grid-column: 1 / -1; }
.form label {
  display: grid; gap: var(--sc-2);
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase; color: var(--sc-ink-soft);
}
.form input, .form textarea {
  font-family: var(--sc-font-text); font-size: var(--sc-t-sm);
  color: var(--sc-ink); background: var(--sc-surface);
  border: 1px solid var(--sc-hairline-strong); border-radius: 8px;
  padding: var(--sc-3); width: 100%; text-transform: none; letter-spacing: normal;
}
.form .btn { grid-column: 1 / -1; justify-self: center; }
.foot {
  display: flex; gap: var(--sc-4); justify-content: center; flex-wrap: wrap;
  font-size: var(--sc-t-xs); color: var(--sc-ink-soft);
}
.foot a { color: var(--sc-ink); text-decoration-color: var(--sc-accent); text-underline-offset: 4px; }

/* ============================================================= responsive == */
@media (max-width: 860px) {
  .doc__wrap--intro { grid-template-columns: 1fr; }
  .intro__portrait { max-width: 13rem; }
  .list a { grid-template-columns: 1fr; gap: var(--sc-1); }
  .list__meta { grid-column: 1; }
  .form { grid-template-columns: 1fr; }
  .chrome { gap: var(--sc-2); padding-inline: var(--sc-3); }
  /* The wordmark goes; the language switch STAYS. Hiding it here made the
     other language unreachable on every phone, which is most of the Spanish
     audience. */
  .chrome__mark { display: none; }
  .chrome__lang { flex: 0 0 auto; }
  /* The route scrolls; the CTA must not shrink or overlap it, which clipped
     the last item behind the button. */
  .chrome__route { overflow-x: auto; scrollbar-width: none; gap: var(--sc-3); min-width: 0; }
  /* Without this the items compress and their own labels wrap to two lines
     instead of the strip scrolling. "What I do" broke in half once Tools made
     it five. */
  .chrome__route a { white-space: nowrap; }
  .chrome__route::-webkit-scrollbar { display: none; }
  .chrome__cta { flex: 0 0 auto; padding-inline: var(--sc-3); }
}


/* =========================================================== v4 additions ==
   The site now has a job: say what he does, prove it, and get the form filled.
   Everything below serves that. */

.open__sub {
  font-size: var(--sc-t-lg); max-width: 34ch;
  color: var(--sc-ink); line-height: 1.45;
}
.open__cta { display: flex; align-items: center; gap: var(--sc-5); flex-wrap: wrap; }
.open__alt {
  color: var(--sc-ink); text-decoration: none;
  border-bottom: 1px solid var(--sc-accent); padding-bottom: 2px;
  font-size: var(--sc-t-sm);
}

/* --- proof: four rooms, named --------------------------------------------- */
.doc--proof { padding-block: clamp(1.5rem, 4vw, 3rem); }
.proof__label {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-ink-soft); margin-bottom: var(--sc-4);
}
.proof {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--sc-5) var(--sc-6);
}
.proof li {
  display: grid; gap: 2px;
  font-family: var(--sc-font-display); font-size: var(--sc-t-lg); font-weight: 500;
  border-left: 2px solid var(--sc-accent); padding-left: var(--sc-3);
}
.proof span {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  color: var(--sc-ink-soft); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
}

/* --- services: the offer -------------------------------------------------- */
.grid--services { align-items: start; }
.service { display: grid; gap: var(--sc-3); align-content: start; }
.service__n {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  color: var(--sc-accent); letter-spacing: var(--sc-track-wide);
}
.service h3 {
  font-family: var(--sc-font-display); font-size: var(--sc-t-xl);
  font-weight: 500; margin: 0; line-height: 1.15;
}
.service p { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); margin: 0; }
.service__cta {
  justify-self: start; color: var(--sc-ink); text-decoration: none;
  font-size: var(--sc-t-sm); font-weight: 500;
  border-bottom: 1px solid var(--sc-accent); padding-bottom: 2px;
}
.service__cta:hover { color: var(--sc-accent); }

/* Writing is now ten real pieces, so the row loses the kicker column. */
#writing .list a { grid-template-columns: 5.5rem minmax(0, 1fr) auto; }
/* Source is the point of this list, so the kicker is coloured per source
   rather than being uniform grey label furniture. */
.list--sourced .list__kicker { color: var(--sc-ink-soft); }
.list--sourced li:has(.list__kicker:not(:empty)) .list__title { max-width: 40rem; text-wrap: balance; }
@media (max-width: 860px) {
  #writing .list a { grid-template-columns: 1fr auto; }
  #writing .list__kicker { grid-column: 1; grid-row: 1; }
  #writing .list__title { grid-column: 1 / -1; grid-row: 2; }
  #writing .list__meta { grid-column: 2; grid-row: 1; text-align: right; }
}
.doc__action { display: flex; gap: var(--sc-3); flex-wrap: wrap; }

@media (max-width: 860px) {
  .open__sub { font-size: var(--sc-t-base); max-width: none; }
  .proof { grid-template-columns: 1fr 1fr; gap: var(--sc-4); }
  .proof li { font-size: var(--sc-t-base); }
}


/* The closing panel has to fit the viewport it lands in, because it sits inside
   a pinned act: anything past the fold simply cannot be reached. Verified at
   1440x900, 1280x720 and 390x844. */
@media (max-height: 820px), (max-width: 860px) {
  /* Anchored to the bottom, not to a percentage. The panel's height is driven
     by its content, so any percentage top overflows on some viewport; a fixed
     offset from the bottom edge cannot. */
  .close__panel {
    bottom: 2.5rem;
    padding: clamp(0.9rem, 2vw, 1.4rem);
    max-height: calc(100dvh - 7rem);
    /* Last-resort reachability on very short viewports (360x640 and below).
       The panel is inside a pinned act, so content past the fold cannot be
       scrolled to by the page; it has to scroll inside its own box. */
    /* overflow-y only. 'overscroll-behavior: contain' was here and it blocks
       scroll chaining in Chrome even when the panel has nothing to scroll, so
       the whole page froze whenever the pointer was over the card. */
    overflow-y: auto;
  }
  .close__panel .sc-display { font-size: var(--sc-t-lg); }
  .close__panel > p { font-size: var(--sc-t-sm); }
  .close__panel .form { margin-top: var(--sc-3); gap: var(--sc-2); }
  .close__panel .form label { gap: 4px; }
  .close__panel .form input,
  .close__panel .form textarea { padding: var(--sc-2) var(--sc-3); }
  .close__panel .btn { padding: var(--sc-2) var(--sc-5); }
  .foot { gap: var(--sc-3); font-size: 0.7rem; }
}
@media (max-height: 700px) {
  /* The line above the form is the first thing to go: the form is the point. */
  .close__panel > p:not(.foot) { display: none; }
  }


/* On a phone the hero copy runs the full width, so a left-to-right scrim does
   nothing for it. Vertical instead, covering only the band the copy occupies. */
@media (max-width: 860px) {
  .plates__hero {
    background: linear-gradient(180deg,
      color-mix(in oklab, var(--sc-canvas) 92%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 88%, transparent) 48%,
      color-mix(in oklab, var(--sc-canvas) 60%, transparent) 68%,
      transparent 82%);
  }
}


/* prefers-reduced-motion was still getting scroll-linked opacity, which is
   motion by any reasonable reading. Everything is pinned on. */
:root.sc-frozen [data-sc-cue] { opacity: 1 !important; transform: none !important; }
:root.sc-frozen .plate--day { opacity: 1 !important; }


/* =========================================================== v11 additions ==
   FREE TOOLS. The pricing calculator shipped on the live site today, so it
   earns a section here in the same slot it holds there: after Writing, before
   Talks. It is the only proof on the page a visitor can use without emailing
   anyone, which makes it the strongest credibility object in the middle. */

.tool {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
  border: 1px solid var(--sc-hairline-strong);
  border-radius: var(--sc-r-lg);
  overflow: hidden;
  color: var(--sc-ink);
  text-decoration: none;
  background: var(--sc-surface);
  transition: transform var(--sc-d-base) var(--sc-ease-out),
              box-shadow var(--sc-d-base) var(--sc-ease-out),
              border-color var(--sc-d-base) var(--sc-ease-out);
}
.tool:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklab, var(--sc-accent) 45%, transparent);
  box-shadow: 0 14px 44px -20px rgba(46, 38, 32, .32);
}

/* The left panel is the argument. Tinted a step darker than the card so the
   equation reads as a quoted object rather than as body copy. */
.tool__panel {
  /* A warm sand wash, not --sc-canvas: the page is already canvas, so that
     value made the left half of the card dissolve into the background and the
     two-panel split stopped reading as one object. */
  background: color-mix(in oklab, #D9C7A8 38%, var(--sc-surface));
  border-right: 1px solid var(--sc-hairline);
  padding: clamp(1.6rem, 3vw, 2.5rem);
  display: grid; align-content: center; gap: var(--sc-3);
}
.tool__chip {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: .14em; text-transform: uppercase; color: var(--sc-ink-soft);
}
.tool__eq {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-sm);
  line-height: 1.6; color: var(--sc-ink);
  border-left: 2px solid var(--sc-accent); padding-left: var(--sc-3);
}
.tool__eqnote { font-size: var(--sc-t-sm); line-height: 1.55; color: var(--sc-ink-soft); margin: 0; }

.tool__body {
  padding: clamp(1.6rem, 3vw, 2.5rem);
  display: flex; flex-direction: column; justify-content: center; gap: var(--sc-3);
}
.tool__label {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: .14em; text-transform: uppercase; color: var(--sc-ink-soft); margin: 0;
}
.tool__body h3 {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.1; margin: 0;
}
.tool__desc { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); margin: 0; max-width: 46ch; }
.tool__cta {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--sc-accent-strong);
}
.tool__cta span { display: inline-block; transition: transform var(--sc-d-fast) var(--sc-ease-out); }
.tool:hover .tool__cta span { transform: translateX(4px); }

@media (max-width: 860px) {
  .tool { grid-template-columns: 1fr; }
  /* Stacked, the offer has to come first. The equation is the supporting
     argument, not the headline. */
  .tool__body { order: -1; }
  .tool__panel { border-right: 0; border-top: 1px solid var(--sc-hairline); }
}


/* =========================================================== v13 additions ==
   The contact form now carries the same six fields the React site posts to
   n8n, plus real busy / error / sent states. More fields means a taller panel
   inside a pinned act, where anything past the fold simply cannot be reached,
   so the sizing below is the part that matters. */

.form select {
  font: inherit; font-size: var(--sc-t-sm);
  color: var(--sc-ink); background: var(--sc-surface);
  border: 1px solid var(--sc-hairline-strong); border-radius: 10px;
  padding: var(--sc-2) var(--sc-3); width: 100%;
}
.form__error {
  margin: 0; font-size: var(--sc-t-sm); color: var(--sc-accent-strong); text-align: left;
}
.form button[disabled] { opacity: .6; cursor: progress; }

.sent { text-align: center; padding-block: var(--sc-5); }
.sent:focus { outline: none; }
.sent__title {
  font-family: var(--sc-font-display); font-size: var(--sc-t-xl);
  font-weight: 500; margin: 0 0 var(--sc-2);
}
.sent p { color: var(--sc-ink-soft); margin: 0; }

/* Six fields do not fit a 640px-tall laptop at the roomy spacing. Tighten
   rather than let the send button fall past the bottom of a pinned act. */
@media (max-height: 780px) {
  .close__panel { bottom: 4vh; padding: var(--sc-4) var(--sc-5); }
  .close__panel .sc-display { font-size: var(--sc-t-lg); }
  .close__lead { display: none; }
  .form { gap: var(--sc-2); }
  .form input, .form textarea, .form select { padding: 6px var(--sc-2); }
  .form textarea { min-height: 3.2rem; }
}

/* Below this the six fields plus the footer do not fit any pinned act at any
   spacing, so the panel scrolls itself rather than pushing the LinkedIn and
   Book-a-call links past an edge nothing can reach. No overscroll-behavior:
   see the note above. */
@media (max-height: 700px) {
  .close__panel { max-height: 88vh; overflow-y: auto; }
}

/* Engine failed to load (blocked, 404, JS error). Set by the try/catch around
   ScrollCraft.mount. Same reveal as the <noscript> block, for the case where
   scripting is ON but the engine specifically is missing. */
.sc-fallback [data-sc-cue],
.sc-fallback [data-sc-in],
.sc-fallback [data-sc-stagger] > *,
.sc-fallback .close__panel {
  opacity: 1 !important; transform: none !important; clip-path: none !important;
}


/* =========================================================== v14 additions ==
   Two languages, the featured deck card, and the fixes from the pre-deploy
   audit that are not one-line edits. */

/* Keyboard focus can land on a block whose reveal has not fired: the browser
   scrolls it just barely into view, below the IntersectionObserver threshold,
   and the focused link sits there at opacity 0. The engine has a fixup for
   cues inside acts but not for data-sc-in in the paper middle. */
.paper [data-sc-in]:focus-within,
.paper [data-sc-in]:has(:focus-visible),
.paper [data-sc-stagger] > *:focus-within {
  opacity: 1 !important; transform: none !important;
}

/* A long unbroken title from a bad feed payload used to push the document
   sideways. Nothing in a list row should ever be able to do that. */
.list__title { overflow-wrap: anywhere; }

/* --- featured talk: the Anthropic LATAM deck ---------------------------- */
.featured {
  display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
  gap: 0; margin-bottom: var(--sc-6);
  border: 1px solid var(--sc-hairline-strong); border-radius: var(--sc-r-lg);
  overflow: hidden; background: var(--sc-surface);
  color: var(--sc-ink); text-decoration: none;
  transition: transform var(--sc-d-base) var(--sc-ease-out),
              box-shadow var(--sc-d-base) var(--sc-ease-out),
              border-color var(--sc-d-base) var(--sc-ease-out);
}
.featured:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklab, var(--sc-accent) 45%, transparent);
  box-shadow: 0 14px 44px -20px rgba(46, 38, 32, .32);
}
.featured__media { background: var(--sc-canvas); }
/* contain, not cover: this is a deck cover with its own title set into it, and
   cropping cut straight through the words. */
.featured__media { display: grid; place-items: center; }
.featured__media img { display: block; width: 100%; height: auto; max-height: 100%; object-fit: contain; }
.featured__body {
  padding: clamp(1.4rem, 3vw, 2.2rem);
  display: flex; flex-direction: column; justify-content: center; gap: var(--sc-2);
}
.featured__label, .featured__cta {
  font-family: var(--sc-font-mono); font-size: var(--sc-t-xs);
  letter-spacing: .12em; text-transform: uppercase; margin: 0;
}
.featured__label { color: var(--sc-ink-soft); }
.featured__cta { color: var(--sc-accent-strong); }
.featured__cta span { display: inline-block; transition: transform var(--sc-d-fast) var(--sc-ease-out); }
.featured:hover .featured__cta span { transform: translateX(4px); }
.featured__body h3 {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.35rem, 2.6vw, 1.8rem); line-height: 1.15; margin: 0;
}
.featured__meta { font-family: var(--sc-font-mono); font-size: var(--sc-t-xs); color: var(--sc-ink-soft); margin: 0; }
.featured__desc { font-size: var(--sc-t-sm); color: var(--sc-ink-soft); margin: 0; }
@media (max-width: 860px) {
  .featured { grid-template-columns: 1fr; }
  .featured__media img { aspect-ratio: 16 / 10; height: auto; }
}

/* Reserve each pinned act's scroll height BEFORE the engine computes it.
   Until mount runs, .act is an ordinary section sized by its own content, then
   the engine gives it span x 100vh and everything below jumps: measured CLS
   0.2165, with .paper moving 635px. Fonts made it worse (late metrics trigger
   the engine's re-layout) but the reflow is the cause, not the fonts.

   These MUST track data-sc-span in index: 1.4 for the opening, 1.25 for the
   close, and the reduced values trimForContext() swaps in. */
#open    { min-height: 140vh; }
#contact { min-height: 125vh; }
@media (prefers-reduced-motion: reduce) {
  #open    { min-height: 100vh; }
  #contact { min-height: 100vh; }
}
@media (hover: none), (pointer: coarse) {
  #open    { min-height: 110vh; }
  #contact { min-height: 130vh; }
}
