/* ═══════════════════════════════════════════════════════════════════════════
   SCREEN 0A — THE CLOSED BOOK.

   Transcribed from prototype/login.html, which is the approved design. The
   previous version of this file drew the cover itself — a gradient for
   leather, pseudo-elements for tooling, a gradient-clipped letter K — and the
   owner rejected it. The closed book is a page of the book: same plate, same
   leather, same ivy, same two candles.

   Only four images load here, all from the public /plate mount: the three
   frame slices and the candle. See the note in login.ejs for why that is
   allowed and everything else is not.
   ═══════════════════════════════════════════════════════════════════════════ */

.gate {
  min-height: 100dvh;
  padding: clamp(0.4rem, 2vw, 2rem) clamp(0.4rem, 2vw, 2rem) 3rem;
}

/* THE CONTAINER IS THE STAGE, NOT THE PAGE. Every cqw on the plate — the cap
   heights, the blend, the sconce width — is a fraction of the SHEET's width,
   and every % padding resolves against the sheet's containing block. Merging
   these two elements into one, as a first attempt at this file did, points
   both at the full-width page instead: at a 1692px window that made cap-top
   1057px and the side padding 342px on a 640px sheet, so the plate was four
   times too tall and the text column was zero pixels wide. */
.gate .stage {
  container-type: inline-size;
  max-width: 640px;
  margin: 0 auto;
}

/* ── the sheet: identical to every other screen ───────────────────────────── */
.gate .sheet {
  position: relative;
  --plate-scale: 1;
  --cap-top: calc(62.5cqw * var(--plate-scale));
  --cap-bot: calc(32.8125cqw * var(--plate-scale));
  --band-split: calc(var(--cap-top) + (100% - var(--cap-top) - var(--cap-bot)) / 2);
  --band-blend: calc(10.7cqw * var(--plate-scale));
  /* A floor under the vine, so the two caps can never meet and draw a hard
     line across the page — see Page.module.css for the full reasoning. */
  --band-min: calc(var(--band-blend) * 2.5);
  width: 100%;
  min-height: calc(var(--cap-top) + var(--cap-bot) + var(--band-min));
  padding: 29% 21% 26%;
  /* the measured mean of the plate's own outermost two pixels */
  background-color: #050704;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.75);
  isolation: isolate;
}
.gate .sheet::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background:
    radial-gradient(60% 34% at 50% 20%, rgba(255, 232, 182, 0.3), transparent 72%),
    radial-gradient(90% 60% at 50% 55%, rgba(120, 88, 40, 0.1), transparent 75%);
  mix-blend-mode: soft-light;
}

/* The vine runs down from the top cap and up from the bottom cap, meeting
   mid-band behind the candles. Bands bleed a pixel vertically and NOT
   horizontally — a widened band redraws its whole copy of the plate wider and
   jogs every gold rule sideways at both joins. */
.gate .plate-back {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: -1;
  isolation: isolate;
  /* A third, full-height copy of the same vine tile .band--t/.band--b use,
     painted behind them (a stacking context's own background always sits
     under its negative-z-index children, so this can only ever show
     through a gap between those two, never over them). No fixed pixel
     overlap between two independently-rasterised layers can be proven
     sufficient at every possible pinch-zoom scale a real device produces —
     the previous fix only made the gap this papers over less likely, not
     impossible. Backing it with more of the SAME pattern, instead of the
     sheet's own near-black, means a worst-case rounding miss reads as a
     faint seam in a busy organic texture rather than "a black line across
     the screen". */
  background-image: url('/plate/frame-top.jpg'), url('/plate/frame-bot.jpg'), url('/plate/frame-mid.jpg');
  background-repeat: no-repeat, no-repeat, repeat-y;
  background-position: center top, center bottom, center top;
  background-size:
    calc(var(--plate-scale) * 100%) auto,
    calc(var(--plate-scale) * 100%) auto,
    calc(var(--plate-scale) * 100%) auto;
}
.gate .band {
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  background-image: url('/plate/frame-mid.jpg');
  background-repeat: repeat-y;
  background-size: calc(var(--plate-scale) * 100%) auto;
}
.gate .band--t {
  /* See Page.module.css's .bandTop for why this is -4px and not -1px: a real
     pinch-zoom rescales the cap image and this repeating tile as separate
     compositor layers, and a 1px overlap left no margin for that rounding
     to expose the sheet's own near-black background as a hairline.

     The bottom edge has the same problem at a second seam: it used to sit
     at exactly the point band--b's own mask-image first reaches full
     opacity — a zero-margin handoff between two independently-rasterised
     layers, not the generous overlap the top edge already gets. The extra
     -4px here pushes it a few pixels past that point, into territory
     band--b is already fully opaque across, the same margin-of-safety fix
     as the top edge. */
  top: calc(var(--cap-top) - 4px);
  bottom: calc(100% - var(--band-split) - var(--band-blend) - 4px);
  background-position: center top;
}
.gate .band--b {
  top: var(--band-split);
  bottom: calc(var(--cap-bot) - 4px);
  background-position: center bottom;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--band-blend));
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--band-blend));
}

.gate .plate-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
}
.gate .sconce {
  position: absolute;
  width: calc(4.102% * var(--plate-scale));
  z-index: 2;
  pointer-events: none;
  top: var(--band-split);
  transform: translateY(-50%);
  animation: gate-flicker 5.5s ease-in-out infinite;
}
.gate .sconce--l {
  left: calc((1 - var(--plate-scale)) * 50% + 6.836% * var(--plate-scale));
}
.gate .sconce--r {
  right: calc((1 - var(--plate-scale)) * 50% + 6.836% * var(--plate-scale));
  transform: translateY(-50%) scaleX(-1);
  animation-delay: -2.3s;
}
.gate .sconce img {
  width: 100%;
  display: block;
}
@keyframes gate-flicker {
  0%, 100% { opacity: 0.94; filter: brightness(1); }
  22% { opacity: 1; filter: brightness(1.09); }
  47% { opacity: 0.9; filter: brightness(0.96); }
  68% { opacity: 1; filter: brightness(1.06); }
  83% { opacity: 0.93; filter: brightness(0.99); }
}

/* ── what is set on the parchment ─────────────────────────────────────────── */
.gate .leaf {
  position: relative;
  z-index: 4;
  text-align: center;
  color: var(--ink, #2b2419);
}

/* Engraving, not a solid shape: the plate around it is finely painted, and a
   gradient-filled device beside it reads as clip art on an oil painting. */
.gate .crest {
  width: 30%;
  max-width: 112px;
  margin: 0.2em auto 0.95em;
  display: block;
  color: var(--aged-gold-dark, #8a6c30);
}
.gate__title {
  font-family: var(--font-title, Georgia, serif);
  font-weight: 700;
  font-size: clamp(1.32rem, 5.6cqw, 2.1rem);
  line-height: 1.14;
  margin: 0;
  letter-spacing: 0.06em;
  color: #241d12;
  text-shadow: 0 1px 0 rgba(255, 251, 238, 0.6);
}
.gate .flourish {
  display: block;
  margin: 0.7em auto 1.05em;
  width: 34%;
  max-width: 132px;
  color: var(--aged-gold-dark, #8a6c30);
  opacity: 0.85;
}
.gate__subtitle {
  font-family: var(--font-title, Georgia, serif);
  font-style: italic;
  font-size: clamp(0.9rem, 3cqw, 1rem);
  line-height: 1.6;
  color: var(--ink-soft, #4a3f2d);
  margin: 0;
}

/* ── the way in: ruled lines and inscriptions, never a pill or a panel ────── */
.gate .entry {
  margin-top: clamp(1.6rem, 6cqw, 2.3rem);
}
.gate .entry label {
  display: block;
  font-family: var(--font-title, Georgia, serif);
  font-size: clamp(0.64rem, 2.5cqw, 0.78rem);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--aged-gold-ink, #745c25);
  margin-bottom: 0.85em;
}
/* A line ruled on the page to write on, not a text box. No fill, no border on
   three sides, no radius: the manuscript rules out floating rectangles and
   modern UI panels, and an input is where that slips back in most easily. */
.gate .field {
  position: relative;
  display: block;
  margin: 0 auto;
  max-width: 17rem;
}
.gate .field input {
  width: 100%;
  font: inherit;
  /* Never below 16px: iOS Safari auto-zooms the whole page in on focus for
     any input rendering smaller than that, and the zoomed-in state it lands
     on outlives this page — a later reload elsewhere in the book can come
     back at that same stuck scale, cropped into a random corner instead of
     fit to the viewport. The old floor (0.98rem, ~15.7px at default root
     size) was just under the line. */
  font-size: clamp(1rem, 3.4cqw, 1.06rem);
  text-align: center;
  letter-spacing: 0.2em;
  color: #3a2f1d;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--aged-gold-dark, #8a6c30);
  border-radius: 0;
  padding: 0.45em 2.1em 0.38em;
  outline: none;
  transition: border-color 180ms;
}
.gate .field input:focus {
  border-bottom-color: #6d5418;
}
.gate .field input::placeholder {
  color: rgba(116, 92, 37, 0.38);
  letter-spacing: 0.34em;
}
/* Chrome paints autofilled fields with its own pale blue, which turns the
   ruled line back into exactly the floating box the manuscript rules out —
   and puts blue on the page before the crown has woken. It cannot be unset,
   only outrun: an absurd transition delay keeps the animated background from
   ever arriving. */
.gate .field input:-webkit-autofill,
.gate .field input:-webkit-autofill:hover,
.gate .field input:-webkit-autofill:focus {
  -webkit-text-fill-color: #3a2f1d;
  caret-color: #3a2f1d;
  transition: background-color 9999s ease-in-out 0s;
}
.gate .peek {
  position: absolute;
  right: 0.1em;
  top: 50%;
  transform: translateY(-50%);
  width: 1.9em;
  height: 1.9em;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  color: rgba(116, 92, 37, 0.6);
  transition: color 180ms;
}
.gate .peek:hover {
  color: var(--aged-gold-ink, #745c25);
}
.gate .peek svg {
  width: 1.15em;
}
.gate .open {
  display: inline-block;
  margin-top: 1.55em;
  padding: 0.66em 2.1em;
  position: relative;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-title, Georgia, serif);
  font-size: clamp(0.78rem, 2.9cqw, 0.95rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #4b3a15;
  /* Same fix as Page.module.css's .onward: a touch-and-hold fires :hover on
     mobile with no real hover to tell it apart, and the wider letter-spacing
     below could otherwise wrap "Open the Book" onto a second line. login.js
     locks this control's rest-measured width the same way useStableWrap
     does for the React-rendered controls (no framework here to hang a hook
     off), and only adds nowrap if that measurement was already one line. */
  transition: color 180ms, letter-spacing 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.gate .open::before,
.gate .open::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--aged-gold-dark, #8a6c30) 22%, var(--aged-gold-dark, #8a6c30) 78%, transparent);
}
.gate .open::before { top: 0; }
.gate .open::after { bottom: 0; }
.gate .open:hover {
  color: #7a5f1c;
  letter-spacing: 0.26em;
}

.gate .denied {
  margin: 1.2em auto 0;
  max-width: 22rem;
  min-height: 1.5em;
  font-family: var(--font-title, Georgia, serif);
  font-style: italic;
  font-size: clamp(0.82rem, 3cqw, 0.96rem);
  line-height: 1.5;
  color: var(--burgundy, #5a2630);
  opacity: 0;
  transition: opacity 420ms;
}
.gate .denied.is-shown {
  opacity: 1;
}

/* Four crown points, none of them lit: the book has not been begun. */
.gate .crowns {
  display: flex;
  justify-content: center;
  gap: 0.85em;
  margin-top: 1.9em;
}
.gate .crowns i {
  width: clamp(13px, 3.4cqw, 17px);
  color: rgba(138, 108, 48, 0.3);
}
.gate .lamb {
  width: clamp(38px, 9cqw, 52px);
  margin: 1.5em auto 0;
  display: block;
  color: rgba(138, 108, 48, 0.5);
}

/* ── the phone crop — DESIGN.md §8.2 ──────────────────────────────────────── */
@media (max-width: 500px) {
  .gate .sheet {
    --plate-scale: 1.18;
    padding: 34% 15% 25%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .gate .sconce,
  .gate .open,
  .gate .denied {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}
