/* ===============================================================
   The Best Place By The Fire

   Shadow theatre. A darkened room, a lamp warming up, an image
   thrown onto a screen — the book's own argument about screen
   fairy tales, rather than an illustration of its subject.

   Warmth is a light SOURCE in a teal dark, not a tint over
   everything. Palette anchored on a teal seed (hue 170), with
   amber as the lamp.
   =============================================================== */

:root {
  /* --- Ground: the darkened room ------------------------------ */
  --bg:          oklch(0.148 0.028 192);
  --bg-deep:     oklch(0.104 0.024 194);
  --surface:     oklch(0.205 0.030 192);
  --line:        oklch(0.310 0.028 190);

  /* --- Brand ------------------------------------------------- */
  --primary:     oklch(0.580 0.070 172);   /* teal — rules, silhouettes  */
  --primary-lit: oklch(0.750 0.080 170);   /* the seed, small highlights */
  --accent:      oklch(0.865 0.135 72);    /* the lamp                   */
  --accent-warm: oklch(0.720 0.150 55);    /* deeper ember, for glow     */

  /* --- Text --------------------------------------------------- */
  --ink:         oklch(0.950 0.012 80);
  --muted:       oklch(0.760 0.016 80);

  /* --- Type --------------------------------------------------- */
  --serif: Alegreya, Georgia, 'Times New Roman', serif;
  --sans:  'Alegreya Sans', system-ui, sans-serif;

  /* Five steps, each ≥1.25 from the last. The previous ramp ran
     14/15/16/17px — four steps inside a 1.07 band — which left the
     h1 carrying the whole hierarchy on weight alone. Collapsing that
     band into one meta step is what lets the headline calm down. */
  --text-meta:     0.875rem;                          /* 14px        */
  --text-body:     1.125rem;                          /* 18px  ×1.29 */
  --text-lede:     1.4375rem;                         /* 23px  ×1.28 */
  --text-h2:       clamp(1.75rem, 3vw, 2.0625rem);    /* →33px ×1.43 */
  --text-h1:       clamp(2.5rem, 6.5vw, 4.125rem);    /* →66px ×2.00 */
  --text-subtitle: clamp(1.25rem, 2.6vw, 1.4375rem);  /* shares lede */

  /* Line-height: four roles, not six ad-hoc values. */
  --lh-display: 1.08;     /* 1.02 left descenders near-touching caps */
  --lh-heading: 1.25;
  --lh-lede:    1.5;
  --lh-body:    1.8;      /* light-on-dark wants the extra leading */

  /* Tracking. Light-on-dark needs type OPENED, not tightened — the
     old h1 ran -0.025em, which is that rule inverted on the largest
     type on the page, and it jammed Alegreya's flared serifs into
     each other. Display is now barely negative; everything else
     opens up. */
  --track-display: -0.005em;
  --track-heading:  0;
  --track-body:     0.01em;
  --track-label:    0.02em;
  --track-code:     0.06em;
  --track-caps:     0.08em;

  /* --- Motion ------------------------------------------------- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  /* --- Layout ------------------------------------------------- */
  /* Measured against real rendered lines, not an alphabet average:
     38rem gave 76ch, over the 45–75 band. Alegreya's mean advance is
     ~0.46em, so 34rem at 18px lands near 66ch. */
  --measure: 34rem;
  --pad:     clamp(1.25rem, 5vw, 2.5rem);

  /* --- Depth -------------------------------------------------- */
  --z-stage: 0;
  --z-page:  1;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--serif);
  font-size: var(--text-body);
  /* Light type on a dark ground reads lighter than it measures — it
     gets extra leading and a touch of tracking. */
  line-height: var(--lh-body);
  letter-spacing: var(--track-body);
  color: var(--ink);
  background: var(--bg);
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }


/* ===============================================================
   The stage
   =============================================================== */

.stage {
  position: fixed;
  inset: 0;
  z-index: var(--z-stage);
  pointer-events: none;
  overflow: hidden;
}

/* The lamp: a warm pool of light thrown from behind the plate. */
.stage__lamp {
  position: absolute;
  top: -18vh;
  left: 50%;
  width: min(150vw, 78rem);
  aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  background:
    radial-gradient(closest-side,
      oklch(0.720 0.150 55 / 0.30) 0%,
      oklch(0.680 0.140 50 / 0.16) 38%,
      oklch(0.600 0.120 45 / 0.06) 62%,
      transparent 78%);
  animation:
    lamp-warm 1900ms var(--ease-out-expo) backwards,
    lamp-flicker 9s ease-in-out 1900ms infinite;
}

/* Corners fall away into the dark. */
.stage__vignette {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(115% 85% at 50% 12%,
      transparent 42%,
      oklch(0.104 0.024 194 / 0.55) 78%,
      oklch(0.104 0.024 194 / 0.92) 100%);
}

.stage__horizon {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: min(42vh, 20rem);
}

.horizon__far   { fill: oklch(0.190 0.030 190); }
.horizon__mid   { fill: oklch(0.165 0.028 191); }
.horizon__near  { fill: oklch(0.128 0.026 193); }

.horizon__trees {
  fill: none;
  stroke: oklch(0.128 0.026 193);
  stroke-width: 2.4;
  stroke-linecap: round;
}

.horizon__birds {
  fill: none;
  stroke: oklch(0.300 0.030 188);
  stroke-width: 1.8;
  stroke-linecap: round;
  /* Alternates rather than loops: a linear reset would snap back. */
  animation: birds-drift 42s ease-in-out infinite alternate;
}


/* ===============================================================
   Page shell
   =============================================================== */

.page {
  position: relative;
  z-index: var(--z-page);
  max-width: 64rem;
  margin: 0 auto;
  padding: clamp(3rem, 9vw, 6rem) var(--pad) clamp(4rem, 10vw, 7rem);
}


/* ===============================================================
   Masthead — the plate in the light
   =============================================================== */

.masthead {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
  margin-bottom: clamp(4rem, 10vw, 7rem);
}

@media (min-width: 56rem) {
  .masthead {
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  }
}

/* The cover, held in the beam. */
.plate {
  margin: 0;
  justify-self: center;
  max-width: 20rem;
  border-radius: 3px;
  overflow: hidden;
  box-shadow:
    0 0 0 1px oklch(0.865 0.135 72 / 0.16),
    0 1.25rem 2.5rem oklch(0.104 0.024 194 / 0.75),
    0 0 5rem oklch(0.720 0.150 55 / 0.24);
  animation: plate-in 1100ms 260ms var(--ease-out-expo) backwards;
}

.masthead__text { animation: text-in 900ms 460ms var(--ease-out-expo) backwards; }

.imprint {
  margin: 0 0 1.25rem;
  font-family: var(--sans);
  font-size: var(--text-meta);
  font-weight: 500;
  letter-spacing: var(--track-label);
  color: var(--accent);
}

/* Weight 600, not 800: Alegreya has no display cut, and its heaviest
   weights are its most calligraphic rather than its most authoritative.
   At 800 the stems fatten while the long extenders stay thin, so the
   gestural bits get relatively MORE prominent — which is what read as
   ornate next to the cover's crisp engraved caps. */
h1 {
  margin: 0;
  font-size: var(--text-h1);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  text-wrap: balance;
  color: var(--ink);
}

.subtitle {
  margin: 0.75rem 0 0;
  font-size: var(--text-subtitle);
  font-style: italic;
  font-weight: 400;
  line-height: var(--lh-heading);
  text-wrap: balance;
  color: var(--accent);
}

.byline {
  margin: 1.5rem 0 0;
  font-family: var(--sans);
  font-size: var(--text-meta);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}

.order { margin: 2.25rem 0 0; }

.promo {
  margin: 0.875rem 0 0;
  font-family: var(--sans);
  font-size: var(--text-meta);
  color: var(--muted);
}

.promo b {
  display: inline-block;
  padding: 0.1em 0.5em;
  border: 1px dashed oklch(0.865 0.135 72 / 0.5);
  border-radius: 3px;
  font-weight: 700;
  letter-spacing: var(--track-code);
  color: var(--accent);
}


/* ===============================================================
   Call to action
   =============================================================== */

.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.9rem 1.75rem;
  border-radius: 4px;
  background: var(--accent);
  color: var(--bg-deep);            /* pale fill → dark text */
  font-family: var(--sans);
  font-size: var(--text-body);
  font-weight: 700;
  text-decoration: none;
  transition: background-color 220ms var(--ease-out-expo),
              transform 220ms var(--ease-out-expo);
}

.cta svg { transition: transform 260ms var(--ease-out-expo); }

.cta:hover {
  background: oklch(0.920 0.115 76);
  transform: translateY(-1px);
}

.cta:hover svg { transform: translateX(3px); }


/* ===============================================================
   Prose
   =============================================================== */

.prose {
  max-width: var(--measure);
  margin: 0 0 clamp(3.5rem, 8vw, 5.5rem);
}

.prose p {
  margin: 0 0 1.375rem;
  text-wrap: pretty;
}

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

.lede {
  font-size: var(--text-lede);
  line-height: var(--lh-lede);
  letter-spacing: 0;
  color: var(--ink);
}

.prose > p:not(.lede):not(.contact) { color: var(--muted); }

h2 {
  margin: 0 0 1.25rem;
  font-size: var(--text-h2);
  font-weight: 700;
  line-height: var(--lh-heading);
  letter-spacing: var(--track-heading);
  text-wrap: balance;
  color: var(--ink);
}

/* A struck match of a rule — the lamp catching the section edge. */
h2::before {
  content: '';
  display: block;
  width: 2.75rem;
  height: 2px;
  margin-bottom: 1.25rem;
  background: linear-gradient(to right, var(--accent), transparent);
}

em { font-style: italic; }


/* ===============================================================
   Written pieces — sits alongside the film as the other way in
   =============================================================== */

.piece {
  display: block;
  margin: 1.75rem 0;
  padding: 1.125rem 1.25rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
  transition: border-color 260ms var(--ease-out-expo),
              transform 260ms var(--ease-out-expo);
}

.piece:hover {
  border-color: oklch(0.865 0.135 72 / 0.55);
  transform: translateY(-2px);
}

.piece__kind {
  display: block;
  margin-bottom: 0.4rem;
  font-family: var(--sans);
  font-size: var(--text-meta);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent);
}

.piece__title {
  display: block;
  font-weight: 700;
  line-height: var(--lh-heading);
  text-wrap: balance;
}

.piece__meta {
  display: block;
  margin-top: 0.4rem;
  font-family: var(--sans);
  font-size: var(--text-meta);
  color: var(--muted);
}


/* ===============================================================
   The film — a static link, not an embed. No third-party JS.
   =============================================================== */

.film {
  display: block;
  margin-top: 2rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  overflow: hidden;
  transition: border-color 260ms var(--ease-out-expo),
              transform 260ms var(--ease-out-expo);
}

.film:hover {
  border-color: oklch(0.865 0.135 72 / 0.55);
  transform: translateY(-2px);
}

.film__frame {
  display: block;
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg-deep);
}

.film__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.86;
  transition: opacity 300ms var(--ease-out-expo),
              transform 500ms var(--ease-out-expo);
}

.film:hover .film__frame img {
  opacity: 1;
  transform: scale(1.025);
}

.film__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

.film__play svg {
  padding: 0.9rem 0.75rem 0.9rem 1.05rem;
  border-radius: 50%;
  background: oklch(0.104 0.024 194 / 0.72);
  color: var(--accent);
  transition: background-color 260ms var(--ease-out-expo),
              color 260ms var(--ease-out-expo);
}

.film:hover .film__play svg {
  background: var(--accent);
  color: var(--bg-deep);
}

.film__meta {
  display: block;
  padding: 1rem 1.25rem 1.125rem;
}

.film__title {
  display: block;
  font-weight: 700;
  line-height: var(--lh-heading);
}

.film__sub {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--sans);
  font-size: var(--text-meta);
  color: var(--muted);
}


/* ===============================================================
   Contact + footer
   =============================================================== */

.contact { margin-top: 1.75rem; }

/* min-height 48px: the underline is only ~35px tall on its own, under
   the 44px minimum tap target on a phone. 48 rather than 44 so it
   clears the floor rather than sitting exactly on it. The border moves
   to an inner span so the rule still hugs the text. */
.contact a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 48px;
  color: var(--accent);
  font-family: var(--sans);
  text-decoration: none;
}

.contact a span {
  padding-bottom: 2px;
  border-bottom: 1px solid oklch(0.865 0.135 72 / 0.35);
  transition: border-color 200ms var(--ease-out-expo);
}

.contact a:hover span { border-bottom-color: var(--accent); }

.footer {
  max-width: var(--measure);
  padding-top: 2.5rem;
  border-top: 1px solid var(--line);
  font-family: var(--sans);
  font-size: var(--text-meta);
  color: var(--muted);
}

.footer p { margin: 0; }


/* ===============================================================
   Focus — default outlines vanish on a dark ground
   =============================================================== */

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


/* ===============================================================
   Motion

   Every animation starts from a state the element can also simply
   BE in. Nothing here gates visibility: if animations never run,
   the page renders complete.
   =============================================================== */

@keyframes lamp-warm {
  from { opacity: 0; transform: translateX(-50%) scale(0.72); }
  to   { opacity: 1; transform: translateX(-50%) scale(1); }
}

/* Firelight, not a strobe: a slow breath at the edge of notice. */
@keyframes lamp-flicker {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.9; }
}

@keyframes plate-in {
  from { opacity: 0; transform: translateY(1.5rem) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

@keyframes text-in {
  from { opacity: 0; transform: translateY(1rem); }
  to   { opacity: 1; transform: none; }
}

/* Percentages on an SVG group resolve against its own bbox, so this is
   a slow lateral drift of a few dozen pixels, not a flight across. */
@keyframes birds-drift {
  from { transform: translateX(-8%); }
  to   { transform: translateX(28%); }
}

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

  .stage__lamp,
  .plate,
  .masthead__text,
  .horizon__birds { animation: none; }

  *, *::before, *::after {
    transition-duration: 1ms !important;
  }

  .cta:hover,
  .film:hover { transform: none; }

  .film:hover .film__frame img { transform: none; }
}
