/* ═══════════════════════════════════════════════════════════════════
   CLAUDIO GLABARE — SEALED
   One screen. Nothing below. The goat keeps the door until Drop II.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* kit values: ink #0A0A0A, cream #E8E2D6, red #D10F1F */
  --ink:      oklch(14.5% 0 90);
  --ink-deep: oklch(9% 0 90);
  --bone:     oklch(91.4% .017 85);
  --bone-dim: oklch(71% .012 85);
  --faint:    oklch(48% .008 85);
  --red:      oklch(54.6% .216 26);
  --red-hi:   oklch(61% .22 26);
  --hair:     oklch(91.4% .017 85 / .14);
  --hair-hi:  oklch(91.4% .017 85 / .3);

  --sans:  "Montserrat", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --roman: "Cinzel", "Trajan Pro", "Times New Roman", serif;

  --pad:  clamp(1.1rem, 3.6vw, 3rem);
  --ease: cubic-bezier(.16, 1, .3, 1);

  /* overture time-scale: 1 on first visit, shorter on repeat visits (set by JS) */
  --t: 1;
}

/* ─────────────────────────── reset ─────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html, body { height: 100%; }
html { background: var(--ink-deep); -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans); font-weight: 400;
  color: var(--bone); background: var(--ink-deep);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow: hidden; overscroll-behavior: none;
}
/* never trap content: JS sets these when the screen is too short, or while typing */
html.can-scroll body, html.is-typing body { overflow: auto; }

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

::selection { background: var(--red); color: var(--bone); }
:focus-visible { outline: 2px solid var(--red-hi); outline-offset: 4px; }

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

/* ═══════════════════ the sealed screen ═══════════════════ */

.seal {
  position: relative; isolation: isolate;
  /* the isolated group needs its own ground: blend modes only see inside it, so
     without this the grain's overlay has nothing to blend with and greys the black */
  background: var(--ink-deep);
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  padding: var(--pad);
  padding-bottom: max(var(--pad), env(safe-area-inset-bottom));
  overflow: hidden;
}

/* the light the eyes throw — drifts with the head, flares when refused */
.seal__glow {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(36% 32% at calc(50% + var(--gx, 0) * 7%) calc(40% + var(--gy, 0) * 5%),
              oklch(54.6% .216 26 / .16) 0%, transparent 72%);
  opacity: 0; transition: opacity calc(var(--t) * 2.4s) ease calc(var(--t) * .7s);
}
.seal__glow::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(42% 38% at calc(50% + var(--gx, 0) * 7%) calc(40% + var(--gy, 0) * 5%),
              oklch(54.6% .216 26 / .38) 0%, transparent 70%);
  opacity: 0; transition: opacity 1.3s ease;
}
.is-awake .seal__glow { opacity: 1; }
.seal.is-refusing .seal__glow::after { opacity: 1; transition-duration: .12s; }

.grain {
  position: absolute; inset: -50%; z-index: 3; pointer-events: none;
  opacity: .2; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 1.4s steps(4) infinite;
}
@keyframes grain {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-3%, 2%); }
  50% { transform: translate(2%, -3%); }
  75% { transform: translate(-2%, -2%); }
}

/* ── corners ── */
.seal__top, .seal__base {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: clamp(.55rem, .68vw, .64rem); font-weight: 500;
  letter-spacing: .3em; text-transform: uppercase; color: var(--faint);
  position: relative; z-index: 4;
}

/* ── the stage: mark, name, status ── */
.seal__stage {
  position: relative; z-index: 4;
  display: grid; justify-items: center; align-content: center;
  gap: clamp(1rem, 3.4svh, 2.6rem);
  text-align: center;
}
.seal.is-refusing .seal__stage { animation: kick .8s linear; }
@keyframes kick {
  0%   { transform: none; }
  14%  { transform: translateY(calc(var(--kick, -1) * 22px)); }
  44%  { transform: translateY(calc(var(--kick, -1) * -6px)); }
  70%  { transform: translateY(calc(var(--kick, -1) * 2px)); }
  100% { transform: none; }
}

/* ── the goat: body, glow and eyes are separate, registered layers ── */
.goat {
  position: relative;
  height: clamp(8.5rem, 36svh, 23rem);
  aspect-ratio: 1081 / 1270;
  perspective: 900px;
}
.seal.is-refusing .goat { animation: lunge .7s var(--ease); }
@keyframes lunge {
  0%   { transform: none; }
  20%  { transform: scale(1.07); }
  100% { transform: none; }
}

/* no preserve-3d: the layers flatten into the head's plane and stack in DOM order, so the
   eyes can never be depth-sorted behind the face (Safari does that with blurred children) */
.goat__head { position: absolute; inset: 0; will-change: transform; }
.goat__head img { position: absolute; inset: 0; width: 100%; height: 100%; }

/* eyes drift a few px further than the face as the head turns (JS sets --ex/--ey) */
.goat__eyes { transform: translate(var(--ex, 0px), var(--ey, 0px)); opacity: 0; }
.goat__glow { transform: translate(var(--ex, 0px), var(--ey, 0px)) scale(1.03); filter: blur(10px) saturate(1.5); opacity: 0; }
.goat__body { opacity: 0; transform: scale(.965); }

/* overture — eyes first, then the head forms around them */
.is-awake .goat__eyes { animation: ignite calc(var(--t) * 1.15s) linear calc(var(--t) * .25s) both; }
.is-awake .goat__glow { animation: bloom calc(var(--t) * 1.6s) ease-out calc(var(--t) * .55s) both; }
.is-awake .goat__body {
  opacity: 1; transform: none;
  transition: opacity calc(var(--t) * 1.9s) ease calc(var(--t) * 1.3s),
              transform calc(var(--t) * 2.2s) var(--ease) calc(var(--t) * 1.3s);
}
@keyframes ignite {
  0%   { opacity: 0; }
  10%  { opacity: .9; }
  16%  { opacity: .08; }
  27%  { opacity: .7; }
  33%  { opacity: .15; }
  58%  { opacity: 1; }
  100% { opacity: 1; }
}
@keyframes bloom { from { opacity: 0; } to { opacity: .8; } }

/* settled: the overture is over — pin end states, then breathe */
.is-settled .goat__eyes { animation: none; opacity: 1; }
.is-settled .goat__body { opacity: 1; transform: none; transition: none; }
.is-settled .goat__glow { opacity: .75; animation: breathe 4.4s ease-in-out infinite; }
@keyframes breathe { 0%, 100% { opacity: .5; } 50% { opacity: .95; } }

/* refused: the eyes flare */
.seal.is-refusing .goat__glow { animation: flare 1.6s ease-out both; }
.seal.is-refusing .goat__eyes { animation: hot 1.6s ease-out; }
@keyframes flare {
  0%   { opacity: 1; filter: blur(12px) saturate(1.6) brightness(2); }
  100% { opacity: .7; filter: blur(10px) saturate(1.5) brightness(1); }
}
@keyframes hot {
  0%   { opacity: 1; filter: brightness(1.75) saturate(1.3); }
  100% { opacity: 1; filter: none; }
}

/* joined the list: a slow blink of acknowledgement */
.seal.is-blink .goat__eyes,
.seal.is-blink .goat__glow { animation: blink .9s ease-in-out; }
@keyframes blink { 0%, 100% { opacity: 1; } 38%, 58% { opacity: 0; } }

/* ── the thin wordmark, opening from the centre ── */
.seal__mark { width: min(80vw, 44rem); color: var(--bone); }
.seal__mark svg {
  width: 100%;
  clip-path: inset(0 50% 0 50%);
  transition: clip-path calc(var(--t) * 1.9s) var(--ease) calc(var(--t) * 2.05s);
}
.is-awake .seal__mark svg, .is-settled .seal__mark svg { clip-path: inset(0 0 0 0); }

/* ── status: the next numeral, its name painted shut ── */
.seal__status {
  position: relative; display: grid; justify-items: center; gap: .65rem;
  min-height: 3.4em;
  opacity: 0; transition: opacity calc(var(--t) * 1.1s) ease calc(var(--t) * 2.75s);
}
.is-awake .seal__status, .is-settled .seal__status { opacity: 1; }

.seal__state {
  display: inline-flex; align-items: center; gap: .85em;
  font-family: var(--roman); font-size: clamp(.82rem, 1.25vw, 1.05rem);
  letter-spacing: .3em; text-transform: uppercase; color: var(--bone);
  margin-right: -.3em;
  transition: opacity .3s ease, transform .5s var(--ease);
}
.seal__state .dot { color: var(--faint); }
.seal__sub {
  font-size: clamp(.58rem, .76vw, .7rem); font-weight: 500;
  letter-spacing: .26em; text-transform: uppercase; color: var(--faint);
  margin-right: -.26em;
  transition: opacity .3s ease;
}

/* the red band — same gesture as the gag on Silentivm */
.bar {
  position: relative; display: inline-block;
  width: 5.6em; height: .92em;
  background: var(--red);
  transform: skewX(-8deg) rotate(-1.6deg);
  border-radius: 1px;
  letter-spacing: 0;
}
.bar::before, .bar::after {
  content: ""; position: absolute; top: 80%;
  width: 2px; background: var(--red); border-radius: 0 0 2px 2px;
}
.bar::before { left: 24%; height: .85em; }
.bar::after  { left: 70%; height: .45em; }

.seal__refuse {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-weight: 700; font-size: clamp(1.25rem, 3.1vw, 2.35rem);
  line-height: 1; letter-spacing: -.01em; text-transform: uppercase;
  color: var(--red-hi);
  opacity: 0; transform: translateY(10px);
  transition: opacity .25s ease, transform .5s var(--ease);
  pointer-events: none; white-space: nowrap;
}
.seal.is-refusing .seal__state,
.seal.is-refusing .seal__sub { opacity: 0; transform: translateY(-8px); }
.seal.is-refusing .seal__refuse { opacity: 1; transform: none; }

/* ═══════════════════ the list ═══════════════════ */

.list {
  position: relative; z-index: 4;
  display: grid; justify-items: center; gap: .85rem;
  width: min(100%, 30rem); margin: 0 auto clamp(.6rem, 2.6svh, 1.8rem);
  opacity: 0; transition: opacity calc(var(--t) * 1.1s) ease calc(var(--t) * 3.15s);
}
.is-awake .list, .is-settled .list { opacity: 1; }

.list__label {
  font-size: .62rem; font-weight: 600; letter-spacing: .3em;
  text-transform: uppercase; color: var(--bone-dim); margin-right: -.3em;
}
.list__label b { color: var(--red-hi); font-weight: 600; }

.list__field { position: relative; display: flex; align-items: center; gap: 1rem; width: 100%; padding-bottom: .75rem; }
.list__field input {
  flex: 1 1 auto; min-width: 0; padding: .35rem 0;
  font-size: clamp(.92rem, 1.1vw, 1rem); color: var(--bone);
}
.list__field input::placeholder { color: var(--faint); }
.list__field button {
  flex: none; padding: .35rem 0;
  font-size: .66rem; font-weight: 600; letter-spacing: .26em; text-transform: uppercase;
  color: var(--red-hi); transition: opacity .3s ease;
}
.list__field button:hover { opacity: .7; }

.list__rule { position: absolute; inset: auto 0 0 0; height: 1px; background: var(--hair-hi); }
.list__rule::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--red);
  transform: scaleX(0); transform-origin: left; transition: transform .8s var(--ease);
}
.list__field:focus-within .list__rule::after { transform: scaleX(1); }

.list__trap { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.list__field button[disabled] { opacity: .45; cursor: progress; }

.list__msg {
  min-height: 1.3em; font-size: .62rem; font-weight: 500; letter-spacing: .22em;
  text-transform: uppercase; color: var(--red-hi);
  opacity: 0; transition: opacity .4s ease;
}
.list__msg.is-on { opacity: 1; }
.list__msg.is-err { color: oklch(74% .16 65); }

/* corners arrive last */
.seal__top, .seal__base { opacity: 0; transition: opacity calc(var(--t) * 1.2s) ease calc(var(--t) * 3.45s); }
.is-awake .seal__top, .is-awake .seal__base,
.is-settled .seal__top, .is-settled .seal__base { opacity: 1; }

/* once settled, cancel the overture's transitions outright so the end state is pinned
   (the refusal crossfade lives on the children, so it keeps its own transitions) */
.is-settled .seal__glow, .is-settled .seal__mark svg, .is-settled .seal__status,
.is-settled .list, .is-settled .seal__top, .is-settled .seal__base { transition: none; }

/* ═══════════════════ RESPONSIVE ═══════════════════ */

@media (max-width: 560px) {
  .seal__top span:last-child, .seal__base span:last-child { display: none; }
  .seal__top, .seal__base { justify-content: center; }
  .seal__state { gap: .6em; letter-spacing: .22em; margin-right: -.22em; }
  .bar { width: 4.4em; }
}

/* short screens (landscape phones): tighten, drop the extras */
@media (max-height: 560px) {
  .goat { height: clamp(5.5rem, 30svh, 11rem); }
  .seal__stage { gap: .7rem; }
  .seal__sub, .seal__base { display: none; }
  .seal__mark { width: min(60vw, 30rem); }
}

/* ═══════════════════ REDUCED MOTION ═══════════════════ */

@media (prefers-reduced-motion: reduce) {
  .grain { display: none; }
  .is-awake .goat__eyes, .is-awake .goat__glow { animation: none; opacity: 1; }
  .is-settled .goat__glow { animation: none; opacity: .75; }
  .seal.is-refusing .seal__stage, .seal.is-refusing .goat,
  .seal.is-refusing .goat__glow, .seal.is-refusing .goat__eyes,
  .seal.is-blink .goat__eyes, .seal.is-blink .goat__glow { animation: none; }
  .goat__body { transform: none; }
}
