/* =========================================================
   OBSERVED — umbrella gate
   Standalone. Does not load or depend on styles.css.
   ========================================================= */

:root {
  --night: #080906;
  --paper: #ece9df;
  --quiet: rgba(236, 233, 223, .44);
  --dormant: rgba(236, 233, 223, .19);
  --rule: rgba(236, 233, 223, .13);
  --rule-lit: rgba(236, 233, 223, .40);
  /* Selection: the amber that runs through the dusk work, dark type on it. */
  --select: #e8b061;

  --serif: "Source Serif 4", Georgia, serif;
  --sans: "Manrope", Arial, sans-serif;
  --pad: clamp(18px, 3.1vw, 50px);
  --ease: cubic-bezier(.22, .72, .16, 1);
}

* { box-sizing: border-box; }

html {
  background: var(--night);
  height: 100%;
}

/* The gate does not scroll. It is a contents page: it holds still, and the
   list of branches scrolls inside it. */
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--night);
  color: var(--paper);
  font: 13px/1.45 var(--sans);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--select);
  color: var(--night);
}

a {
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

/* =========================================================
   HOVER FILM — behind the contents page, never in front of it

   The gate stays a contents page: the film is a held breath behind
   the type, dimmed by a scrim so every row keeps its contrast.
   A branch with no matching <video> simply shows nothing.
   ========================================================= */

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

.gate-film {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .75s var(--ease);
}

.gate-film.is-visible { opacity: 1; }

/* The scrim sits above the film and below the type. */
.gate-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top,
    rgba(8, 9, 6, .93) 0%,
    rgba(8, 9, 6, .62) 55%,
    rgba(8, 9, 6, .78) 100%);
}

/* Place and month, the way a print is pencilled on the back: small, low
   contrast, above the scrim. Every photograph and film carries one unless it
   sits in a collection that already labels it. */
.gate-stamp {
  position: absolute;
  right: var(--pad);
  bottom: clamp(12px, 2vh, 22px);
  z-index: 2;
  margin: 0;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(236, 233, 223, .5);
  opacity: 0;
  transition: opacity .75s var(--ease);
}

.gate-stamp.is-visible { opacity: 1; }

.gate-head,
.gate {
  position: relative;
  z-index: 1;
}

/* =========================================================
   TRANSIT — leaving the gate for LINES

   Rails run out to the right, the pressed row brightest among
   them. Transform and opacity only: no stroke geometry, no
   layout, so the whole departure stays on the compositor.
   ========================================================= */

.gate-transit {
  position: fixed;
  inset: 0;
  z-index: 9;
  overflow: hidden;
  pointer-events: none;
  background: var(--night);
  opacity: 0;
  animation: transit-ground .14s linear forwards;
}

.gate-transit i {
  position: absolute;
  left: 0;
  height: 1px;
  width: 100%;
  background: var(--paper);
  transform: scaleX(0);
  transform-origin: left center;
  animation: transit-rail .46s cubic-bezier(.16, .84, .3, 1) forwards;
}

/* The row that was pressed reads as the line being taken. */
.gate-transit i.is-taken {
  height: 2px;
}

@keyframes transit-ground {
  to { opacity: 1; }
}

@keyframes transit-rail {
  to { transform: scaleX(1); }
}

/* =========================================================
   HEAD
   ========================================================= */

/* The gate is fixed height, so the rights line lives in the head rather than
   a footer — it costs no vertical space against the three-and-a-half rows. */
.gate-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 54px;
  padding: 14px var(--pad) 0;
}

.gate-rights {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .14em;
  color: var(--dormant);
  white-space: nowrap;
}

.gate-mark {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--quiet);
}

.gate-origin {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--quiet);
  white-space: nowrap;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--dormant);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}

.gate-origin:hover,
.gate-origin:focus-visible {
  color: var(--paper);
  border-color: var(--quiet);
}

/* =========================================================
   GATE — the air above the list is deliberate
   ========================================================= */

.gate {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: calc(100dvh - 68px);
  padding: clamp(60px, 12vh, 150px) var(--pad) clamp(38px, 7vh, 84px);
  overflow: hidden;
}

/* =========================================================
   BRANCHES — a contents page, not a menu
   ========================================================= */

/* Three and a half rows are the window: the half row beneath the third is
   what tells you the list continues. Scrolling snaps row to row, so a branch
   is only ever half shown at the edge of the window, never after a scroll.
   --rows is measured by gate.js from the real first row, because the row
   height is fluid type; the max-height below is only the fallback. */
.branches {
  border-top: 1px solid var(--rule);
  max-height: var(--rows, 68vh);
  /* On a short viewport flex may shrink this below three rows; min-height:0
     lets it, and the list stays scrollable, so no row is ever unreachable. */
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scroll-snap-type: y mandatory;
  /* The half row is the affordance; the scrollbar would only add chrome. */
  scrollbar-width: none;
}

.branches::-webkit-scrollbar { display: none; }

.branch {
  scroll-snap-align: start;
}

.branch {
  display: grid;
  grid-template-columns: clamp(38px, 5vw, 64px) minmax(0, auto) 1fr auto;
  align-items: baseline;
  column-gap: clamp(14px, 2.4vw, 34px);
  padding: clamp(16px, 2.3vh, 30px) 0 clamp(18px, 2.6vh, 34px);
  border-bottom: 1px solid var(--rule);
  transition: border-color .5s var(--ease);
}

.branch-index {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .14em;
  color: var(--quiet);
  transition: color .45s var(--ease);
}

.branch-name {
  font-family: var(--serif);
  font-size: clamp(44px, 7.4vw, 104px);
  font-weight: 400;
  line-height: .9;
  letter-spacing: -.035em;
  transition: color .45s var(--ease), transform .55s var(--ease);
}

.branch-suffix {
  margin-left: .62em;
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--quiet);
  white-space: nowrap;
  transition: color .45s var(--ease);
}

.branch.is-live:hover .branch-suffix,
.branch.is-live:focus-visible .branch-suffix {
  color: var(--paper);
}

.branch.is-dormant .branch-suffix {
  color: var(--dormant);
}

.branch-subject {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--quiet);
  transition: color .45s var(--ease);
}

/* DREAMS & DESOLATION's description only, per request. The name wraps to
   two lines (it's much longer than any other branch's), which was pushing
   the auto-sized name column wide enough to squeeze the subject into a
   narrow, four-line sliver far to the right. Capping that column's width
   lets the subject sit on one line, and aligning the row to its bottom
   edge (instead of the default first-line baseline) puts it beside
   "\\ observed" the way a single-line branch name naturally would. */
.branch[data-branch="dreams-desolation"] .branch-subject {
  text-align: left;
}
.branch[data-branch="dreams-desolation"] {
  grid-template-columns: clamp(38px, 5vw, 64px) minmax(0, 640px) 1fr auto;
  align-items: end;
}

.branch-state {
  justify-self: end;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--quiet);
  transition: color .45s var(--ease), transform .55s var(--ease);
}

/* live */

.branch.is-live .branch-name {
  color: var(--paper);
}

.branch.is-live .branch-state {
  font-size: 15px;
  letter-spacing: 0;
}

.branch.is-live:hover,
.branch.is-live:focus-visible {
  border-bottom-color: var(--rule-lit);
  outline: 0;
}

.branch.is-live:hover .branch-index,
.branch.is-live:hover .branch-subject,
.branch.is-live:focus-visible .branch-index,
.branch.is-live:focus-visible .branch-subject {
  color: var(--paper);
}

.branch.is-live:hover .branch-name,
.branch.is-live:focus-visible .branch-name {
  transform: translateX(.06em);
}

.branch.is-live:hover .branch-state,
.branch.is-live:focus-visible .branch-state {
  color: var(--paper);
  transform: translateX(9px);
}

/* dormant — dimness carries the meaning; the label makes it honest */

.branch.is-dormant {
  cursor: default;
}

.branch.is-dormant .branch-index,
.branch.is-dormant .branch-name,
.branch.is-dormant .branch-subject,
.branch.is-dormant .branch-state {
  color: var(--dormant);
}

/* =========================================================
   STUDIO — quieter, and outside the list entirely
   ========================================================= */

.studio {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: clamp(30px, 5vh, 62px) 0 0;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dormant);
  cursor: default;
}

.studio-mark {
  width: 5px;
  height: 5px;
  border: 1px solid currentColor;
  border-radius: 50%;
}

/* =========================================================
   ARRIVAL
   ========================================================= */

.gate-mark,
.branch,
.studio {
  animation: gate-rise .85s var(--ease) both;
}

.branches .branch:nth-child(1) { animation-delay: .10s; }
.branches .branch:nth-child(2) { animation-delay: .19s; }
.branches .branch:nth-child(3) { animation-delay: .28s; }
.branches .branch:nth-child(4) { animation-delay: .37s; }
.branches .branch:nth-child(5) { animation-delay: .46s; }
.branches .branch:nth-child(6) { animation-delay: .55s; }
.studio { animation-delay: .67s; }

@keyframes gate-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================
   NARROW
   ========================================================= */

@media (max-width: 720px) {
  .branch {
    grid-template-columns: clamp(30px, 9vw, 44px) 1fr auto;
    row-gap: 12px;
  }

  .branch-index   { grid-area: 1 / 1 / 2 / 2; }
  .branch-state   { grid-area: 1 / 3 / 2 / 4; }
  .branch-name    { grid-area: 2 / 1 / 3 / 4; }
  .branch-subject { grid-area: 3 / 1 / 4 / 4; }

  .branch.is-live:hover .branch-state,
  .branch.is-live:focus-visible .branch-state {
    transform: none;
  }
}

/* =========================================================
   REDUCED MOTION
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
  .gate-mark,
  .branch,
  .studio {
    animation: none;
  }

  * {
    transition-duration: .01ms !important;
  }
}
