/* DREAMS & DESOLATION — the pure dark of insomnia, and what it turns
   into when it starts to feel like a dream instead of a wound.
   Independent of the other themes, like waylights.css / hues.css: loads
   observed.css for shared tokens and restates head/foot rules locally.

   No scroll. Instead of a line of photos, this is a single dark room --
   an oversized canvas (.dd-canvas) larger than the viewport, holding
   3 columns of photos (7 real photos) evenly
   spaced across it with no overlap, panned by the cursor
   (dreams-desolation.js) rather than by scrolling. Moving the mouse is
   like turning your head in a dark bedroom: most of what's around you
   stays hidden, and finding the next thing takes actually looking
   for it.

   Two more photos sit outside that room entirely, each in its own
   fixed anchor -- always lit, never gated behind the spotlight, no
   scrolling needed. door-shadow (.dd-anchor-left) is flush at the
   left edge, vertically centered. cave-light (.dd-anchor-right) is
   bigger, flush at the right edge, centered both ways in its own
   column. So is the header/eyebrow/footer text.

   Two more things do the rest of the work, unchanged from before:

   1. A page-wide "vision" spotlight (fixed veil, radial-gradient mask)
      follows the cursor, keeping the room's photos near-black except
      right around the cursor.
   2. A slow, continuous breathing pulse on every image (room or
      anchor), desynced per frame, so nothing settles into a restful,
      fully-lit state.

   Below 760px / on touch devices, panning a hidden canvas by mouse
   doesn't work as an interaction, so it falls back to a plain
   centered, stacked, scrolling list instead. */

/* The five-column row (door-shadow, column A, column B, column C,
   cave-light) is a full-bleed layout with no centered max-width
   container -- .dd is position:fixed inset:0, actual viewport edge to
   viewport edge. Column widths are fixed (280 + 195 + 210 + 195 + 280
   = 1160px total) but the page itself is any real window width, so the
   gaps between columns have to be computed from 100vw, not a hardcoded
   reference width, or they only come out even on one specific window
   size. --dd-gap is that one gap value (there are 6: both outer edges
   plus the 4 between columns), floored at 16px so things don't
   collapse into negative offsets on a narrow-but-not-mobile window. */
:root {
  --dd-gap: max(16px, calc((100vw - 1160px) / 6));
}

.lines-head { position: fixed; top: 0; left: 0; right: 0; z-index: 41; display:flex; justify-content:space-between; align-items:center; gap:24px; padding:20px var(--pad); font-size:12px; letter-spacing:.13em; }
.lines-head a { padding:8px 0; }
a:focus-visible, button:focus-visible { outline:2px solid var(--paper); outline-offset:5px; }
.eyebrow { font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:#a4a399; }
.dd-eyebrow { position: fixed; top: 58px; left: 0; right: 0; z-index: 20; padding: 0 var(--pad); margin: 0; }
.madrid-foot { position: fixed; bottom: 0; left: 0; right: 0; z-index: 41; display:flex; justify-content:space-between; align-items:baseline; gap:20px; padding:0 var(--pad) 16px; font-size:12px; color:#a4a399; }
.madrid-foot a { display:inline-block; padding:10px 0; }
.rights { font-size:10px; letter-spacing:.12em; color:var(--dormant); white-space:nowrap; }
.madrid-foot-tags { font-size:10px; letter-spacing:.1em; text-transform:lowercase; color:rgba(236,233,223,.78); white-space:nowrap; }
@media(max-width:760px) { .madrid-foot-tags { display:none; } }

/* This page is a room, not a passage -- back to the gate's own
   overflow:hidden, fixed-viewport behaviour (unlike WAYLIGHTS/LINES). */
html { height: 100%; }
body { height: 100%; overflow: hidden; background: #050403; }

.dd { position: fixed; inset: 0; z-index: 5; }

/* THE OPENING — the page holds full black for a beat, then fades out
   to reveal the already-emerging room underneath (the frames' own
   dd-emerge animations are running the entire time, staggered up to
   ~3.1s in), rather than the room just appearing the instant the CSS
   loads. Reads as eyes adjusting to a dark room, not a light switching
   on -- and not adjusting smoothly: two quick flickers catch a bare
   glimpse of the room before it's gone again, like something seen for
   a half-second too long in the dark, ahead of the true reveal. The
   veil itself is pure black (#000), a level darker than the room's own
   near-black background, so the hold at the start reads as deeper than
   the darkness it's about to give way to.

   The flicker dips use a linear timing-function (set per-keyframe,
   below) rather than the page's usual eased curve -- eased, they read
   as slow, deliberate fades and the whole thing starts to feel like a
   stall rather than a flicker. Only the final segment, the true reveal,
   switches back to var(--ease) for a normal soft fade-out. Total time
   kept close to a plain fade (2.2s vs. the old 2.6s) so the flickers
   read as an interruption of something quick, not extra length on top
   of something slow.

   z-index above everything, including the anchors/header/footer (41)
   and the vision veil (40). pointer-events:none so it never blocks the
   one click autoplay usually needs; dreams-desolation.js removes the
   element once the animation ends. */
.dd-open {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #000;
  pointer-events: none;
  animation: dd-open-flicker 2.2s linear forwards;
}

@keyframes dd-open-flicker {
  0%   { opacity: 1; }
  28%  { opacity: 1; }
  30%  { opacity: .85; }  /* first flicker -- barely gives, then shuts again */
  32%  { opacity: 1; }
  46%  { opacity: 1; }
  48%  { opacity: .62; }  /* second, deeper -- something glimpsed */
  49%  { opacity: .9; }
  51%  { opacity: 1; animation-timing-function: var(--ease); }
  100% { opacity: 0; }    /* the true reveal, eased, from 51% to 100% */
}

@media (prefers-reduced-motion: reduce) {
  .dd-open { display: none; }
}

/* ============================================================
   THE ROOM — a fixed, viewport-sized clipping window (.dd-room)
   with a much larger canvas (.dd-canvas) inside it. The canvas is
   what dreams-desolation.js actually translates as the mouse moves;
   .dd-room only exists to hide whatever scrolls past its edges.
   ============================================================ */

.dd-room {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.dd-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 1100px;
  height: 725px;
  will-change: transform;
}

.dd-frame {
  position: absolute;
  margin: 0;
  opacity: 0;
  animation: dd-emerge 1.8s var(--ease) forwards;
}

.dd-frame img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 1px;
  animation: dd-breathe 7s ease-in-out infinite;
}

/* Three columns across the 1100x725 canvas. All FIVE columns across the
   page -- door-shadow, column A, column B, column C, cave-light -- are
   now evenly distributed: 40px at both outer edges and 40px between
   every adjacent pair, same math as a plain space-evenly row (widths
   280 + 195 + 210 + 195 + 280 = 1160, page width 1400, leaving 240px
   split across 6 equal gaps of 40px). Because the canvas isn't panned
   at any desktop viewport width (see dreams-desolation.js), its
   coordinate space lines up 1:1 with the fixed-position anchors', so
   the two systems can share one set of numbers. Each room column is
   two or three frames stacked with a small gap, all landing on the
   same top (100px) and bottom (~645px):

     column A -- forest-trunks, water-glint stacked (2 x 3:4, 24px gap)
     column B -- garden-veil, station-board, shore-watch stacked
                 (3 x 5:4, inflated to 210px, 20px gaps, so the three
                 together span the same height as column A's two)
     column C -- ember-cloud, branches-sky stacked (2 x 3:4, 24px gap) --
                 branches-sky was swapped down here in favour of
                 water-glint taking its old spot in column A */
.dd-frame-forest   { left: calc(var(--dd-gap) * 2 + 280px); top: 100px;   width: 195px; animation-delay: .1s; }
.dd-frame-water    { left: calc(var(--dd-gap) * 2 + 280px); top: 384px;   width: 195px; animation-delay: .3s; }
.dd-frame-garden   { left: calc(var(--dd-gap) * 3 + 475px); top: 100px;   width: 210px; animation-delay: .5s; }
.dd-frame-station  { left: calc(var(--dd-gap) * 3 + 475px); top: 288px;   width: 210px; animation-delay: .7s; }
.dd-frame-shore    { left: calc(var(--dd-gap) * 3 + 475px); top: 476.8px; width: 210px; animation-delay: .9s; }
.dd-frame-ember    { left: calc(var(--dd-gap) * 4 + 685px); top: 100px;   width: 195px; animation-delay: 1.1s; }
.dd-frame-branches { left: calc(var(--dd-gap) * 4 + 685px); top: 384px;   width: 195px; animation-delay: 1.3s; }

/* ============================================================
   THE ANCHORS — door-shadow (left) and cave-light (right), pinned
   outside the pannable room and above the vision veil (z-index 41 >
   .dd-vision's 40), so they stay fully lit and visible no matter
   where the cursor is. They keep the same breathing-pulse animation
   as every other photo, just not the spotlight darkness.

   door-shadow and cave-light are both 280px, sitting at the same
   --dd-gap margin from their respective edges as every other column's
   gap -- see the column comment above for the full space-evenly math.
   Both vertically centered in the space between the header and footer.
   ============================================================ */

/* pointer-events:none on the anchor containers themselves -- each is a
   tall (top:100 to bottom:70, i.e. nearly full viewport height) fixed
   box at z-index 41, and being transparent, an ordinary click still
   hit-tests against its full rectangle even where nothing is painted.
   .dd-anchor-right in particular overlaps .dd-player's corner (bottom
   right), so without this, a click on the vinyl there was silently
   swallowed by the empty anchor box sitting above it in z-order --
   this is the actual cause of "the vinyl isn't clickable", not any
   timing issue in the JS. pointer-events:auto is restored on the
   frame itself so the photo (and cave-light's hover caption) still
   receives clicks/hover normally. */
.dd-anchor-left {
  position: fixed;
  left: var(--dd-gap);
  top: 100px;
  bottom: 70px;
  z-index: 41;
  display: flex;
  align-items: center;
  pointer-events: none;
}

.dd-anchor-right {
  position: fixed;
  right: var(--dd-gap);
  top: 100px;
  bottom: 70px;
  width: 280px;
  z-index: 41;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.dd-anchor-left .dd-frame, .dd-anchor-right .dd-frame {
  position: static;
  margin: 0;
  pointer-events: auto;
}

.dd-frame-door { width: 280px; animation-delay: .9s; }
.dd-frame-cave { width: 280px; animation-delay: .1s; }

/* Vignette -- fades the edges of cave-light to transparent so its
   rectangular border dissolves into the page's near-black background
   instead of reading as a hard-edged frame. The ellipse is wider than
   it is tall (65% vs 82%) so the left/right sides fade in sooner than
   the top/bottom -- cave-light's sides were meant to "camouflage" into
   the dark, more than a plain corner-vignette would give it. Not
   applied to door-shadow. */
.dd-frame-cave img {
  -webkit-mask-image: radial-gradient(ellipse 65% 82% at 50% 50%, black 45%, transparent 100%);
  mask-image: radial-gradient(ellipse 65% 82% at 50% 50%, black 45%, transparent 100%);
}

/* Cave-light's caption -- hidden until hovered (or focused, via the
   tabindex on the figure, for keyboard reach), then fades in to the
   LEFT of the photo, never over it, drifting slightly inward as it
   appears. */
.dd-anchor-right .dd-frame-cave {
  position: relative;
  outline: none;
}

.dd-cave-quote {
  position: absolute;
  top: 50%;
  right: calc(100% + 20px);
  width: 220px;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: var(--serif);
  font-style: italic;
  font-size: 13px;
  line-height: 1.6;
  letter-spacing: .01em;
  color: var(--paper);
  text-align: right;
  text-shadow: 0 1px 8px rgba(0,0,0,.85);
  opacity: 0;
  transform: translateY(-50%) translateX(10px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  pointer-events: none;
}

.dd-anchor-right .dd-frame-cave:hover .dd-cave-quote,
.dd-anchor-right .dd-frame-cave:focus-visible .dd-cave-quote,
.dd-anchor-right .dd-frame-cave:focus-within .dd-cave-quote {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Station-board's caption -- unlike cave-light, there's no open margin
   beside it (it's boxed tightly between garden-veil and shore-watch in
   the same column, with column A -- forest-trunks/water-glint -- only
   a --dd-gap away to the left), so this can't sit in genuinely empty
   space the way cave-light's does. It still goes to the left rather
   than over the photo, plain text with a shadow (no background scrim)
   like cave-light's own caption, narrow enough to stay close to the
   gap: it may brush the edge of forest-trunks/water-glint behind it,
   but never sits on top of station-board itself. */
.dd-frame-station { position: relative; outline: none; }

.dd-station-quote {
  position: absolute;
  top: 50%;
  right: calc(100% + 16px);
  width: 170px;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: var(--serif);
  font-style: italic;
  font-size: 12px;
  line-height: 1.55;
  letter-spacing: .01em;
  color: var(--paper);
  text-align: right;
  text-shadow: 0 1px 8px rgba(0,0,0,.85);
  opacity: 0;
  transform: translateY(-50%) translateX(10px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  pointer-events: none;
}

.dd-frame-station:hover .dd-station-quote,
.dd-frame-station:focus-visible .dd-station-quote,
.dd-frame-station:focus-within .dd-station-quote {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

.dd-frame-cave     img { animation-duration: 6.4s; animation-delay: 1.6s; }
.dd-frame-forest   img { animation-duration: 8.2s; animation-delay: .4s; }
.dd-frame-branches img { animation-duration: 7.1s; animation-delay: 2.4s; }
.dd-frame-door     img { animation-duration: 6.8s; animation-delay: 1.1s; }
.dd-frame-garden   img { animation-duration: 9s;   animation-delay: 3s; }
.dd-frame-station  img { animation-duration: 7.6s; animation-delay: .9s; }
.dd-frame-shore    img { animation-duration: 8.6s; animation-delay: 2.1s; }
.dd-frame-ember    img { animation-duration: 6.2s; animation-delay: .2s; }
.dd-frame-water    img { animation-duration: 7.4s; animation-delay: 2.7s; }

@keyframes dd-emerge {
  from { opacity: 0; transform: translateY(10px); filter: brightness(.28); }
  to   { opacity: 1; transform: translateY(0);    filter: brightness(1); }
}

@keyframes dd-breathe {
  0%, 100% { filter: brightness(.62); }
  50%      { filter: brightness(1); }
}

@media (prefers-reduced-motion: reduce) {
  .dd-frame { opacity: 1; animation: none; }
  .dd-frame img { animation: none; filter: brightness(1); }
}

/* ============================================================
   THE VISION SPOTLIGHT — a fixed, page-wide near-black veil with a
   soft circular window cut around the cursor (dreams-desolation.js
   tracks pointer position into --dd-x/--dd-y). Sits above the room
   and the eyebrow/player, but the header, footer and both anchor
   photos (.dd-anchor-left, .dd-anchor-right) now sit above IT
   (z-index 41 vs. 40), so they read as exempt from the spotlight
   rather than gated by it.
   ============================================================ */

.dd-vision {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  background: rgba(3, 3, 2, .93);
  -webkit-mask-image: radial-gradient(circle at var(--dd-x, 50%) var(--dd-y, 42%),
    transparent 0, transparent 90px, black 230px);
  mask-image: radial-gradient(circle at var(--dd-x, 50%) var(--dd-y, 42%),
    transparent 0, transparent 90px, black 230px);
  opacity: 0;
  animation: dd-vision-in 1.8s var(--ease) .2s forwards;
}

@keyframes dd-vision-in { to { opacity: 1; } }

@media (pointer: coarse), (prefers-reduced-motion: reduce) {
  .dd-vision { display: none; }
}

/* quiet "now playing" credit, echoing ORIGIN's vinyl but smaller and
   without cover art. Fixed in the bottom-right corner, clear of the
   footer bar. */

.dd-player {
  position: fixed;
  right: var(--pad);
  bottom: 64px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.dd-player a {
  font-size: 10px;
  letter-spacing: .03em;
  color: #a4a399;
  padding: 0;
  white-space: nowrap;
}

.dd-player a:hover, .dd-player a:focus-visible { color: var(--paper); }

.vinyl {
  position: relative;
  width: 56px;
  height: 56px;
  flex: none;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  background: radial-gradient(circle at 42% 38%, #201d17, #0a0906 70%);
  box-shadow: 0 2px 12px rgba(0,0,0,.5);
  animation: vinyl-spin 3.6s linear infinite;
  animation-play-state: paused;
}

.vinyl[aria-pressed="true"] { animation-play-state: running; }
.vinyl:hover, .vinyl:focus-visible { box-shadow: 0 2px 12px rgba(0,0,0,.5), 0 0 0 1px var(--rule); }

.vinyl-grooves {
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  background: repeating-radial-gradient(circle at 50% 50%,
    transparent 0 7%, rgba(255,255,255,.05) 7% 7.6%, transparent 7.6% 13%);
  pointer-events: none;
}

.vinyl-hole {
  position: absolute;
  inset: 46%;
  border-radius: 50%;
  background: #0d0d0a;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08);
}

@keyframes vinyl-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) { .vinyl { animation: none; } }

/* ============================================================
   MOBILE / TOUCH FALLBACK — panning a hidden canvas by mouse isn't a
   workable interaction without a mouse. Below 760px (or on any
   coarse pointer), drop the room entirely and go back to a plain
   centered, stacked, scrolling list -- still small, still dark, just
   reachable by touch.
   ============================================================ */

@media (max-width: 760px), (pointer: coarse) {
  html, body { height: auto; overflow-y: auto; overflow-x: hidden; }
  .lines-head, .dd-eyebrow, .madrid-foot { position: static; }
  .dd { position: static; padding: 8px 0 40px; }

  .dd-anchor-left, .dd-anchor-right { position: static; left: auto; right: auto; top: auto; bottom: auto; width: auto; display: flex; flex-direction: column; align-items: center; gap: 40px; padding: 20px var(--pad) 0; }

  .dd-room { position: static; overflow: visible; }
  .dd-canvas { position: static; width: auto; height: auto; display: flex; flex-direction: column; align-items: center; gap: 40px; padding: 20px var(--pad) 0; }

  .dd-frame { position: static; width: 100% !important; max-width: 280px; left: auto !important; top: auto !important; }

  .dd-player { position: static; margin: 40px auto 0; }
}
