/* =================================================================
   First Winter — Delphine Gray
   Sevra Design Studio · Showcase concept
   ================================================================= */


/* ---------- Tokens (Convention #8) ---------- */

:root {
  --bg:            #1F2A1F;
  --bg-deep:       #14201A;
  --bg-soft:       #25312A;
  --ink:           #E8E3CC;
  --ink-soft:      rgba(232, 227, 204, 0.78);
  --ink-faint:     rgba(232, 227, 204, 0.55);
  --ink-quiet:     rgba(232, 227, 204, 0.38);
  --rule:          rgba(232, 227, 204, 0.13);
  --rule-strong:   rgba(232, 227, 204, 0.22);
  --accent:        #D4A04E;
  --accent-soft:   rgba(212, 160, 78, 0.55);
  --accent-faint:  rgba(212, 160, 78, 0.20);

  --font-display:  'EB Garamond', Georgia, 'Times New Roman', serif;
  --font-body:     'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --font-brand:    'Fraunces', Georgia, serif;

  --step-eyebrow:        0.75rem;
  --step-meta:           0.875rem;
  --step-body:           clamp(1rem, 0.95rem + 0.2vw, 1.0625rem);
  --step-stanza:         clamp(1.25rem, 1.05rem + 0.85vw, 1.625rem);
  --step-section-title:  clamp(1.875rem, 1.4rem + 1.6vw, 2.625rem);
  --step-hero:           clamp(2.75rem, 1.5rem + 5vw, 5.5rem);
  --step-book-title:     clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  --step-caption:        clamp(1.5rem, 1rem + 2vw, 2.625rem);

  --container:    1200px;
  --measure:      36rem;

  --sevra-band-h:  36px;
  --topbar-h:      60px;

  /* Sevra showcase band tokens — used only inside .sevra-band.
     The band is Sevra's surface, so it carries Sevra's palette and
     a system mono fallback. Keeps the band visually identical across
     showcase builds regardless of each build's own palette. */
  --sevra-bg:      #2B221A;
  --sevra-ink:     #F4ECDC;
  --sevra-accent:  #D6A357;
  --sevra-mono:    ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --ease-out:     cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out:  cubic-bezier(0.65, 0, 0.35, 1);

  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 12px;
}


/* ---------- Reset & base ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  /* scroll-padding-top is exactly chrome (band + topbar). Any extra buffer
     here would show as a body-bg strip above every snapped panel. Section
     headers carry their own scroll-margin-top for anchor-jump breathing.
     Per Convention #33. */
  scroll-padding-top: calc(var(--sevra-band-h) + var(--topbar-h));
  /* Proximity (not mandatory) so the snap nudges toward the nearest panel
     when the reader stops scrolling, but never traps them. The rest of the
     page (colophon, books, readings, contact) doesn't carry scroll-snap-
     align so it scrolls freely.

     Desktop one-input-one-panel precision is delivered by setupPanelSnap()
     in script.js — a small wheel/keyboard shim that intercepts in the panel
     area only and releases native scroll at the edges. Mandatory was tried
     and rejected: with no forward snap target after panel 6, mandatory
     traps the user on the last panel. Touch and reduced-motion users skip
     the shim and rely on this CSS proximity snap directly. */
  scroll-snap-type: y proximity;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 400;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }
button { font: inherit; cursor: pointer; background: transparent; border: 0; color: inherit; }

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--accent-soft);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 200ms ease, text-decoration-color 200ms ease;
}
a:hover, a:focus-visible {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

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


/* ---------- Utilities ---------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -48px;
  left: 1rem;
  background: var(--accent);
  color: var(--bg);
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: 500;
  z-index: 1000;
  transition: top 200ms ease;
}
.skip-link:focus { top: 1rem; outline: 2px solid var(--ink); }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}


/* ---------- Sevra showcase band ----------
   Sevra's surface — uses Sevra brand colors, not this build's.
   Stays visually identical across showcase examples so the band
   reads as Sevra's wrapper, not Delphine Gray's chrome. */

.sevra-band {
  background: var(--sevra-bg);
  color: var(--sevra-ink);
  height: var(--sevra-band-h);
  border-bottom: 1px solid rgba(0, 0, 0, 0.5);
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
}

.sevra-band__inner {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.04em;
}

/* "Sd" monogram — Sevra brand mark. Small dark box with serif "S"
   in vellum and italic "d" in Sevra gold. */
.sevra-band__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: #000000;
  border-radius: 3px;
  flex-shrink: 0;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  color: var(--sevra-ink);
  letter-spacing: -0.01em;
  padding-bottom: 1px;
  margin-right: 0.25rem;
}
.sevra-band__logo em {
  font-style: italic;
  font-weight: 400;
  color: var(--sevra-accent);
}

.sevra-band__brand  { font-weight: 500; }
.sevra-band__sep    { color: rgba(244, 236, 220, 0.4); }
.sevra-band__role,
.sevra-band__client { color: rgba(244, 236, 220, 0.85); }

/* Anchor wrapping logo + brand wordmark — returns to the main marketing
   site. Inherits color so the logo and wordmark keep their treatments. */
.sevra-band__home {
  display: inline-flex;
  align-items: center;
  color: inherit;
  text-decoration: none;
  transition: color 180ms var(--ease-out);
}
.sevra-band__home:hover { color: var(--sevra-accent); }

.sevra-band__back {
  margin-left: auto;
  color: var(--sevra-accent);
  font-family: var(--sevra-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 180ms var(--ease-out);
  flex-shrink: 0;
  white-space: nowrap;
}
.sevra-band__back:hover { border-bottom-color: var(--sevra-accent); }

/* Tight viewports: drop the middle "Showcase build" segment so the
   client name still fits next to "Sevra Design Studio". */
@media (max-width: 540px) {
  .sevra-band__role { display: none; }
  .sevra-band__sep:nth-of-type(1) { display: none; }
}


/* ---------- Topbar ---------- */

.topbar {
  position: sticky;
  top: var(--sevra-band-h);
  z-index: 50;
  background: rgba(31, 42, 31, 0.92);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid var(--rule);
  height: var(--topbar-h);
}

.topbar__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.5rem;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.topbar__name {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1;
  text-decoration: none;
  color: var(--ink);
}
.topbar__name:hover { color: var(--accent); }

.topbar__nav { display: flex; gap: 1.875rem; align-items: center; }
.topbar__nav a {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1;
  text-decoration: none;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
  transition: color 180ms ease;
}
.topbar__nav a:hover { color: var(--accent); }

.topbar__menu-toggle {
  display: none;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.55rem;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  transition: border-color 180ms ease, color 180ms ease;
}
.topbar__menu-toggle:hover { border-color: var(--accent-soft); color: var(--accent); }

@media (max-width: 759px) {
  .topbar__menu-toggle { display: inline-flex; }
  .topbar__nav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--rule);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px);
    transition:
      opacity 220ms var(--ease-out),
      transform 220ms var(--ease-out),
      visibility 0s linear 220ms;
  }
  .topbar.is-open .topbar__nav {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition:
      opacity 220ms var(--ease-out),
      transform 220ms var(--ease-out);
  }
  .topbar__nav a {
    padding: 1.125rem 1.5rem;
    border-top: 1px solid var(--rule);
    font-size: 1rem;
  }
}


/* ---------- Hero ---------- */

.hero {
  min-height: calc(100vh - var(--sevra-band-h) - var(--topbar-h));
  min-height: calc(100dvh - var(--sevra-band-h) - var(--topbar-h));
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 4rem 1.5rem;
  position: relative;
  overflow: hidden;
  background-color: var(--bg);
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
/* Photographic backdrop. The image sits behind the type and is darkened
   by a forest-tinted gradient so the type stays readable while the photo
   sets atmosphere. A slow, infinite alternating scale animation gives the
   image a subtle Ken Burns drift — the page breathes rather than sits flat. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: url('assets/hero-window-snow.png') center/cover no-repeat;
  z-index: 0;
  animation: kenburns 32s ease-in-out infinite alternate;
  transform-origin: center center;
}
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(31, 42, 31, 0.55) 0%,
    rgba(31, 42, 31, 0.78) 60%,
    rgba(31, 42, 31, 0.92) 100%
  );
  z-index: 1;
}

.hero__inner {
  max-width: 50rem;
  margin: 0 auto;
  position: relative;
  z-index: 2;
  scroll-margin-top: 1rem;
}

.hero__eyebrow {
  font-family: var(--font-body);
  font-size: var(--step-eyebrow);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 2.25rem;
  opacity: 0;
  animation: hero-fade 1100ms 200ms var(--ease-out) forwards;
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-hero);
  line-height: 1.04;
  letter-spacing: -0.018em;
  margin: 0;
  color: var(--ink);
}

.hero__line { display: inline-block; opacity: 0; }
.hero__line--1 { animation: hero-fade 1100ms 800ms var(--ease-out) forwards; }
.hero__line--2 {
  font-style: italic;
  color: var(--accent);
  font-weight: 500;
  transform: translateY(10px);
  animation: hero-rise 1200ms 1500ms var(--ease-out) forwards;
}

@keyframes hero-fade { to { opacity: 1; } }
@keyframes hero-rise { to { opacity: 1; transform: none; } }

.hero__cue {
  display: block;
  margin-top: 4rem;
  color: var(--ink-quiet);
  opacity: 0;
  animation:
    hero-fade 1100ms 2300ms var(--ease-out) forwards,
    cue-bob 2200ms 3400ms var(--ease-in-out) infinite;
}

/* Desktop-only hint: keyboard alternative to scrolling.
   Hidden on touch / coarse-pointer devices. The pseudo-element appears
   above the SVG arrow inside .hero__cue and bobs along with it. */
@media (hover: hover) and (pointer: fine) {
  .hero__cue::before {
    content: "scroll or press ↓";
    display: block;
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--ink-faint);
    margin-bottom: 0.625rem;
  }
}

@keyframes cue-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}


/* ===========================================================
   POEM — First Winter
   Six full-bleed photo-and-verse panels. Each panel = one stanza
   over its scene. Soft scroll-snap keeps each panel landing on
   the visible viewport without trapping the reader. Slow Ken
   Burns drift on the photo gives each panel quiet motion.
   =========================================================== */

.poem-panels {
  background: #000;
}

.panel {
  position: relative;
  min-height: calc(100vh - var(--sevra-band-h) - var(--topbar-h));
  min-height: calc(100dvh - var(--sevra-band-h) - var(--topbar-h));
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  scroll-snap-align: start;
  /* stop: always forces every wheel scroll past a panel to land on it,
     producing the "slideshow" feel on desktop. Proximity remains the
     container snap-type so non-panel sections (colophon, books, etc.)
     scroll freely; stop: always only fires at panel boundaries. */
  scroll-snap-stop: always;
}

.panel__photo {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  z-index: 0;
  animation: kenburns 26s ease-in-out infinite alternate;
  transform-origin: center center;
  will-change: transform;
}
/* Stagger the start of each panel's drift so adjacent panels don't
   move in lockstep when both are partially in view. */
.panel:nth-child(2n) .panel__photo { animation-direction: alternate-reverse; }
.panel:nth-child(3n) .panel__photo { animation-duration: 30s; }

.panel__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.22) 0%,
    rgba(0, 0, 0, 0.55) 45%,
    rgba(0, 0, 0, 0.55) 65%,
    rgba(0, 0, 0, 0.30) 100%
  );
  z-index: 1;
}

.panel__verse {
  position: relative;
  z-index: 2;
  max-width: 36rem;
  padding: 0 1.5rem;
  text-align: center;
}
/* Desktop: widen the verse column so long poetic lines stay on one line.
   Mobile column width is naturally constrained by viewport + padding;
   the cap only matters at desktop verse font sizes. */
@media (min-width: 760px) {
  .panel__verse { max-width: 50rem; }
}

.panel__verse .stanza {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.375rem, 1.05rem + 1.25vw, 2rem);
  line-height: 1.55;
  color: var(--ink);
  margin: 0;
  text-shadow:
    0 2px 6px rgba(0, 0, 0, 0.65),
    0 8px 28px rgba(0, 0, 0, 0.45);
}

/* Each poetic line is a block-level span so hanging-indent treatment
   can target individual lines (text-indent only applies to the first
   line of a block, so plain <br> separators wouldn't work). */
.stanza__line { display: block; }

/* Forced mid-line breaks for mobile only. Each <br class="mobile-break">
   sits at a deliberate caesura inside a stanza__line so that on mobile
   every poetic line renders as two visible rows with consistent hanging
   indent. On desktop the breaks are hidden and the full line flows on
   one row as designed. */
@media (min-width: 760px) {
  .mobile-break { display: none; }
}

/* Mobile: flush-left with hanging indent on wrapped continuations, plus
   a slightly tighter font so the halves of each forced-break line fit
   on a single visible row at common phone widths. The hanging indent
   on stanza__line applies uniformly to both forced breaks (.mobile-break)
   and any natural wraps that still occur on the narrowest viewports.

   Desktop keeps centered text (verse column was widened to 50rem in
   the desktop media query above so wraps are rare). */
@media (max-width: 759px) {
  .panel__verse { text-align: left; }
  .stanza__line {
    padding-left: 1.5em;
    text-indent: -1.5em;
  }
  .panel__verse .stanza {
    font-size: clamp(1.125rem, 0.85rem + 1vw, 1.375rem);
  }
}

/* Down-cue: subtle "more below" hint at the bottom of each panel.
   Hidden on the last panel (the colophon below is the natural next move). */
.panel__cue {
  position: absolute;
  left: 50%;
  bottom: 2rem;
  transform: translateX(-50%);
  z-index: 2;
  font-family: var(--font-body);
  font-size: 1.5rem;
  color: var(--ink);
  opacity: 0.55;
  animation: panel-cue-bob 2.4s ease-in-out infinite;
  pointer-events: none;
  user-select: none;
}
.panel:last-child .panel__cue { display: none; }

@keyframes kenburns {
  from { transform: scale(1); }
  to   { transform: scale(1.07); }
}

/* Panel cue-bob is distinct from the hero cue-bob because .panel__cue is
   absolute-positioned with left: 50% and uses translate(-50%, ...) to
   keep itself centered while bobbing — the hero cue is a block-level
   element and bobs on Y only. Two keyframes blocks with the same name
   collide (last wins) and the hero cue inherits the translate(-50%),
   shifting it left by half its block width. Keep the names distinct. */
@keyframes panel-cue-bob {
  0%, 100% { transform: translate(-50%, 0); opacity: 0.55; }
  50%      { transform: translate(-50%, 6px); opacity: 0.85; }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before,
  .panel__photo,
  .panel__cue { animation: none; }
}


/* ---------- Section headers ---------- */

.section-header {
  text-align: center;
  margin-bottom: 3.5rem;
  /* scroll-padding-top on html already accounts for sticky chrome.
     scroll-margin-top here is just additional breathing room. */
  scroll-margin-top: 1rem;
}

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step-eyebrow);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1rem;
}

.section-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-section-title);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--ink);
}
.section-title em { font-style: italic; color: var(--accent); }


/* ---------- Colophon ---------- */

.colophon { padding: 6rem 0; border-top: 1px solid var(--rule); background: var(--bg-soft); }

.colophon__grid {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
  max-width: 880px;
  margin: 0 auto;
  align-items: start;
}
@media (min-width: 760px) {
  .colophon__grid {
    grid-template-columns: 320px 1fr;
    gap: 4rem;
    align-items: center;
  }
}

.colophon__portrait { margin: 0; max-width: 360px; }
.colophon__portrait img { border-radius: var(--radius-sm); width: 100%; }

.colophon__text {
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.75;
  color: var(--ink-soft);
  max-width: var(--measure);
}
.colophon__text p { margin: 0 0 1.125rem; }
.colophon__text p:last-child { margin-bottom: 0; }
.colophon__text em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  color: var(--ink);
  font-size: 1.0625em;
}


/* ---------- Books ---------- */

.books { padding: 6rem 0; border-top: 1px solid var(--rule); }
.books__list {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 960px;
}
.book {
  padding: 2.5rem 0;
  border-bottom: 1px solid var(--rule);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  /* Mobile source order: cover, year, body — stacks naturally without explicit areas. */
}
@media (min-width: 700px) {
  .book {
    grid-template-columns: 90px 1fr 260px;
    grid-template-areas: "year body cover";
    gap: 2.5rem;
    align-items: start;
  }
  .book__year  { grid-area: year; }
  .book__body  { grid-area: body; }
  .book__cover { grid-area: cover; }
}
.book:first-child { padding-top: 0; }
.book:last-child  { border-bottom: none; padding-bottom: 0; }

.book__cover {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  margin: 0 auto;
}
@media (min-width: 700px) {
  .book__cover { max-width: none; margin: 0; }
}

.book__year {
  font-family: var(--font-body);
  font-size: var(--step-meta);
  font-weight: 500;
  color: var(--accent);
  letter-spacing: 0.08em;
  margin: 0;
}
.book__body { min-width: 0; }
.book__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: var(--step-book-title);
  line-height: 1.2;
  letter-spacing: -0.005em;
  margin: 0 0 0.375rem;
  color: var(--ink);
}
.book__publisher {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--ink-faint);
  letter-spacing: 0.04em;
  margin: 0 0 1rem;
}
.book__note {
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 38rem;
  margin: 0;
}


/* ---------- Readings & Letters ---------- */

.readings { padding: 6rem 0; border-top: 1px solid var(--rule); background: var(--bg-soft); }
.readings__grid {
  display: grid;
  gap: 3.5rem;
  grid-template-columns: 1fr;
  max-width: 920px;
  margin: 0 auto;
}
@media (min-width: 760px) {
  .readings__grid {
    grid-template-columns: 1.4fr 1fr;
    gap: 4rem;
    align-items: start;
  }
}

.readings__list { list-style: none; margin: 0; padding: 0; }

.reading {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.25rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 480px) {
  .reading {
    grid-template-columns: 9.5rem 1fr;
    gap: 1.75rem;
    align-items: baseline;
  }
}
.reading:first-child { padding-top: 0; }
.reading:last-child { border-bottom: none; padding-bottom: 0; }

.reading__date {
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--accent);
  letter-spacing: 0.02em;
  margin: 0;
}
.reading__venue {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 1.1875rem;
  line-height: 1.3;
  color: var(--ink);
  margin: 0;
}
.reading__city {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--ink-faint);
  margin: 0.25rem 0 0;
}

.letters {
  background: var(--bg);
  padding: 2rem 1.75rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--rule);
}
.letters__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  font-size: 1.5rem;
  margin: 0 0 1rem;
  color: var(--accent);
  letter-spacing: -0.005em;
}
.letters p {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}
.letters p:last-child { margin-bottom: 0; }


/* ---------- Contact ---------- */

/* Contact closes the page. The photo strip at the top of the section
   re-introduces the page's photographic vocabulary in the back half
   (the colophon, books, and readings runs are type-only) and gives
   the closer real emotional weight. The strip's bottom edge fades
   into the section background so the photo dissolves into the
   "Write to me." beat below rather than ending in a hard edge.
   Echoes the hero's full-bleed-photo bookend without copying it. */
.contact {
  padding: 0 0 5rem;
}

.contact__photo {
  position: relative;
  width: 100%;
  height: clamp(280px, 42vh, 460px);
  background-image: url('assets/contact-hands-water.png');
  background-size: cover;
  /* 35% horizontal favors the left side of the source where the hands sit
     (relevant on mobile, where the strip aspect crops horizontally). 75%
     vertical biases toward the lower portion of the photo where the hands
     and pebbles are (relevant on desktop, where the wide strip aspect
     crops vertically). One rule, both viewports. */
  background-position: 35% 85%;
  background-repeat: no-repeat;
  margin-bottom: 4.5rem;
}
.contact__photo::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Top fades from --bg-soft (the readings section above) so the photo
     emerges from it; bottom fades to --bg (the contact body below) so
     it dissolves into the closer. Fade ranges kept symmetric and tight
     (15% / 15%) so the photo's central 70% reads cleanly without
     either edge eating into the hands. */
  background: linear-gradient(
    180deg,
    var(--bg-soft) 0%,
    transparent 15%,
    transparent 85%,
    var(--bg) 100%
  );
}

/* Desktop strip is taller than the mobile baseline. The source photo's
   subject (both hands + sweater cuff + pebbles) spans ~39% of its
   vertical, and at the original 460px max ceiling the visible cover-
   crop was just 44% of the photo height — leaving the hands pinned
   against both fade edges. The taller window gives the subject room
   to breathe with the fades sitting in water/pebble context above
   and below rather than clipping the wrists and fingertips. */
@media (min-width: 760px) {
  .contact__photo {
    height: clamp(600px, 65vh, 600px);
  }
}

.contact__body {
  max-width: var(--measure);
  margin: 0 auto;
  text-align: center;
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.65;
  color: var(--ink-soft);
}

.contact__email {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.125rem);
  margin: 1.5rem 0 1.75rem;
  letter-spacing: -0.005em;
}
.contact__email a {
  color: var(--accent);
  text-decoration: none;
  transition: color 200ms ease;
}
.contact__email a:hover { color: var(--ink); }
.contact__note { font-size: 0.9375rem; color: var(--ink-faint); margin: 0; }


/* ---------- Contact link copy affordance ---------- */

/* No underline on .contact-link (mailto/tel anchors). Per the
   no-underline preference: brass color carries the link affordance
   when present, vellum-on-hover signals interaction. The
   .contact__email-specific rule above sets the brass color for the
   prominent email; the inline letters@ link inherits its parent's
   ink color and just needs the global underline suppressed. */
.contact-link {
  text-decoration: none;
  color: var(--accent);
  transition: color 200ms ease;
}
.contact-link:hover { color: var(--ink); }

.copy-affordance {
  display: inline-flex;
  align-items: center;
  margin-left: 0.35em;
  vertical-align: -0.1em;
  opacity: 0.55;
  transition: opacity 200ms ease;
}
.contact-link:hover .copy-affordance,
.contact-link:focus-visible .copy-affordance { opacity: 1; }

@media (pointer: coarse) {
  .copy-affordance { display: none; }
}


/* ---------- Copy status toast ---------- */

.copy-status {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%) translateY(0.5rem);
  background: var(--accent);
  color: var(--bg);
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 500;
  padding: 0.625rem 1.125rem;
  border-radius: var(--radius-md);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms, transform 200ms;
  z-index: 1000;
}
.copy-status.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* ---------- Footer Sevra credit (Convention #30) ---------- */

.site-footer {
  padding: 3rem 0;
  border-top: 1px solid var(--rule);
  background: var(--bg);
}

.site-footer__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  text-align: center;
}
@media (min-width: 760px) {
  .site-footer__inner {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

.site-footer__copy {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--ink-faint);
  margin: 0;
}
.site-footer__credit { margin: 0; }
.site-footer__social {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink-soft) !important;
  text-decoration: none;
  font-size: 0.9375rem;
  line-height: 1.6;
}
.site-footer__social:hover {
  color: var(--accent) !important;
}

.social-icon {
  display: block;
  flex-shrink: 0;
  text-transform: none;
}


/* ---------- Reveal animations for non-cinema elements ---------- */

.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 850ms var(--ease-out),
    transform 850ms var(--ease-out);
}
.reveal.is-revealed { opacity: 1; transform: none; }

.book.reveal:nth-child(1) { transition-delay:   0ms; }
.book.reveal:nth-child(2) { transition-delay: 100ms; }
.book.reveal:nth-child(3) { transition-delay: 200ms; }


/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; transition: none; }
  .hero__eyebrow,
  .hero__line,
  .hero__cue { opacity: 1; transform: none; animation: none; }
}