/* ==========================================================================
   THE GREY CITY — access layer
   ONE family: a system grotesque. Mono is a second VOICE — kickers, readouts,
   buttons — not a second family.
   ========================================================================== */

:root{
  --grey-00:#f7f8f8;  --grey-05:#eceeef;  --grey-10:#dfe2e4;
  --grey-20:#c9ced1;  --grey-40:#9aa1a6;  --grey-60:#5f676d;
  --grey-80:#2a2f34;  --ink:#0b0e11;

  --violet:#9a4dff;  --cyan:#00e5ff;  --amber:#ffa000;
  --mint:#00ff95;    --red:#ff2b46;

  --bg:var(--grey-00);
  --fg:var(--ink);
  --fg-dim:var(--grey-60);
  --fg-faint:var(--grey-40);
  --rule:rgba(20,23,26,.13);
  --accent:var(--violet);

  --sans:ui-sans-serif,system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Roboto Mono",monospace;

  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-6:24px;
  --s-8:32px; --s-12:48px; --s-16:64px; --s-24:96px; --s-32:128px;

  --pad:clamp(20px,4.4vw,72px);
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-key:cubic-bezier(.7,0,.2,1);
}

*{margin:0;padding:0;box-sizing:border-box}
svg{flex-shrink:0}

html{background:var(--bg); scroll-behavior:auto}
body{
  font-family:var(--sans); color:var(--fg); background:var(--bg);
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
:where(a){color:inherit;text-decoration:none}

.mono{font-family:var(--mono)}
.dim{color:var(--fg-faint)}
.eyebrow{font-family:var(--mono); font-size:10px; letter-spacing:.28em;
  text-transform:uppercase; color:var(--fg-dim)}

/* ================================================================= GATE == */
#gate{
  position:fixed; inset:0; z-index:100;
  display:grid; place-content:center; justify-items:center; gap:var(--s-8);
  background:var(--bg);
  transition:opacity 1.1s var(--ease), visibility 1.1s;
}
html[data-state="open"] #gate,
html[data-state="crossing"] #gate{opacity:0; visibility:hidden; pointer-events:none}
#gateKey{width:132px; height:132px; color:var(--fg); overflow:visible}
#gateKeyTurn{transform-box:view-box; transform-origin:0 0}
#gateRead{font-family:var(--mono); font-size:12px; letter-spacing:.24em;
  color:var(--fg-dim); font-variant-numeric:tabular-nums}
#gateNote{font-family:var(--mono); font-size:10px; letter-spacing:.28em;
  min-height:1em; text-transform:uppercase}

/* ================================================================ STAGE == */
#stage{
  position:fixed; inset:0; width:100%; height:100%; display:block; z-index:0;
  opacity:0; transition:opacity 1.6s var(--ease) .2s;
}
html[data-state="open"] #stage{opacity:1}
#grain{
  position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.5;
  background-image:repeating-linear-gradient(0deg,rgba(20,23,26,.028) 0 1px,transparent 1px 3px);
}

/* =============================================================== TOPBAR == */
.topbar{
  position:fixed; top:0; left:0; right:0; z-index:6;
  display:flex; align-items:center; gap:var(--s-4);
  padding:var(--s-6) var(--pad);
  opacity:0; transform:translateY(-6px); pointer-events:none;
  transition:opacity .9s var(--ease) .9s, transform .9s var(--ease) .9s;
}
html[data-state="open"] .topbar{opacity:1; transform:none}
.topbar .mark{width:14px; height:27px; color:var(--fg)}
.tag{font-size:10px; letter-spacing:.3em; color:var(--fg-faint)}
.depth{margin-left:auto; font-size:10px; letter-spacing:.3em; color:var(--fg-faint);
  font-variant-numeric:tabular-nums}

/* =============================================================== SHELL == */
#shell{position:relative; z-index:2}

/* EVERY CHAPTER IS A LANDING PAGE. Full height, its own composition, and no
   two consecutive ones share an alignment — that alternation is what stops a
   long scroll reading as one page repeated. */
.ch{
  min-height:118svh; position:relative;
  padding:var(--s-24) var(--pad) var(--s-16);
  display:grid;
}
/* the first chapter clears the fixed bar — the headline was running straight
   through "ACCESS LAYER" */
.ch:first-child{padding-top:calc(var(--s-24) + var(--s-12))}
/* the empty observation beat does not need a full screen of scrolling to
   itself — it is a pause, not a place */
.ch[data-ch="observation"]{min-height:56svh}
.ch[data-align="bl"]{align-content:end; justify-items:start}
.ch[data-align="tl"]{align-content:start; justify-items:start}
.ch[data-align="br"]{align-content:end; justify-items:end; text-align:right}
.ch[data-align="c"] {align-content:center; justify-items:center; text-align:center}
.ch[data-align="tr"]{align-content:start; justify-items:end; text-align:right}

.ch-in{max-width:min(58ch,100%)}
.ch-in>*+*{margin-top:var(--s-6)}
.ch[data-align="c"] .ch-in{max-width:min(30ch,100%)}

.kicker{font-family:var(--mono); font-size:10px; letter-spacing:.3em;
  color:var(--fg-dim); text-transform:uppercase}

.big{
  font-size:clamp(46px,10vw,150px); line-height:.88;
  letter-spacing:-.04em; font-weight:600; margin-left:-.055em;
}
.mid{font-size:clamp(30px,5.2vw,72px); line-height:1.02;
  letter-spacing:-.03em; font-weight:600; margin-left:-.045em}

/* NO SERIF. It was doing the "literary" thing under the headlines and reads
   wrong here — the world is machine-made, so the fragments speak in the same
   grotesque as everything else, just larger and lighter than body copy. */
.frag-line{
  font-family:var(--sans); font-weight:400;
  font-size:clamp(19px,2.4vw,31px);
  line-height:1.36; letter-spacing:-.012em;
  color:var(--grey-80); max-width:27ch;
}
.ch[data-align="br"] .frag-line,
.ch[data-align="tr"] .frag-line{margin-left:auto}
.ch[data-align="c"]  .frag-line{margin-inline:auto}

.body{font-size:clamp(15px,1.4vw,18px); line-height:1.6;
  color:var(--grey-80); max-width:32ch}

/* a data readout, dropped in where the simulation is describing itself */
.readout{
  font-family:var(--mono); font-size:10px; letter-spacing:.16em;
  color:var(--fg-faint); display:grid; gap:2px;
}
.readout b{font-weight:400; color:var(--fg-dim)}

/* ================================================================ VISIT == */
.visit{
  display:inline-flex; align-items:center; gap:var(--s-4);
  padding:var(--s-4) var(--s-8) var(--s-4) var(--s-6);
  background:var(--ink); color:var(--grey-00);
  border:0; cursor:pointer; font-family:var(--mono);
  font-size:12px; letter-spacing:.28em; font-weight:600;
  clip-path:polygon(0 0,calc(100% - 10px) 0,100% 10px,100% 100%,10px 100%,0 calc(100% - 10px));
  transition:background .35s var(--ease), color .35s var(--ease);
}
.visit:hover{background:var(--accent); color:#fff}
.visit-key{width:13px; height:25px; color:currentColor;
  transform-box:view-box; transform-origin:0 0;
  transition:transform .55s var(--ease-key)}
.visit:hover .visit-key{transform:rotate(90deg)}

/* ================================================================ INDEX == */
.frags{list-style:none; display:grid; gap:0; width:100%; max-width:1100px}
.frag{
  display:grid; grid-template-columns:56px 1fr auto; align-items:baseline;
  gap:var(--s-4); padding:var(--s-6) 0; border-top:1px solid var(--rule);
  font-family:var(--mono); font-size:clamp(12px,1.5vw,15px); letter-spacing:.12em;
  color:var(--fg-faint); cursor:default; position:relative;
  transition:color .3s var(--ease), padding-left .45s var(--ease);
}
.frag:last-child{border-bottom:1px solid var(--rule)}
.frag-id{color:var(--fg-dim)}
.frag-state{font-size:10px; letter-spacing:.22em}
.frag[data-open="1"]{color:var(--fg); cursor:pointer}
.frag[data-open="1"] .frag-state{color:var(--accent)}
.frag[data-state="ACCESS RESTRICTED"] .frag-state{color:var(--red)}
.frag[data-state="GENERATING"] .frag-state{color:var(--accent)}
/* approaching a locked area makes it resolve a little, then lose it again */
.frag:hover{padding-left:var(--s-4); color:var(--grey-80)}
.frag:hover .frag-name{animation:corrupt .9s steps(3,end) 1}
@keyframes corrupt{
  0%,100%{opacity:1; letter-spacing:.12em}
  33%{opacity:.55; letter-spacing:.30em}
  66%{opacity:.85; letter-spacing:.06em}
}

/* ============================================================= CROSSING == */
#crossing{
  position:fixed; inset:0; z-index:200;
  display:grid; place-content:center; justify-items:center; gap:var(--s-8);
  background:var(--bg); opacity:0; visibility:hidden;
  transition:opacity .8s var(--ease), visibility .8s;
}
html[data-state="crossing"] #crossing{opacity:1; visibility:visible}
html[data-state="crossing"] #shell,
html[data-state="crossing"] .topbar{opacity:0; transition:opacity .5s var(--ease)}
#crossKey{width:132px; height:132px; color:var(--fg); overflow:visible}
#crossKeyTurn{transform-box:view-box; transform-origin:0 0;
  transition:transform 1.5s var(--ease-key)}
#crossNote{font-size:10px; letter-spacing:.3em; color:var(--fg-dim);
  min-height:1em; text-transform:uppercase; text-align:center}

/* ================================================================= FILM ==
   The crossing video. Black, full-bleed, above everything. */
#film{
  position:fixed; inset:0; z-index:300; background:#000;
  display:none; place-content:center;
}
html[data-state="film"] #film{display:grid}
#filmVid{width:100%; height:100%; object-fit:cover; display:block}
#filmSkip{
  position:absolute; right:var(--s-6); bottom:var(--s-6);
  padding:var(--s-2) var(--s-6); font-size:10px; letter-spacing:.24em;
  background:rgba(255,255,255,.12); color:#fff; border:1px solid rgba(255,255,255,.3);
  cursor:pointer; clip-path:var(--notch,none);
}

/* reveal on approach — one class, driven by an observer */
.rise{opacity:0; transform:translateY(18px);
  transition:opacity 1s var(--ease), transform 1s var(--ease)}
.rise.in{opacity:1; transform:none}

/* ================================================================ PHONE ==
   A re-composition. The site stays PORTRAIT; only the game asks to rotate.
   Media blocks sit at the end of the file so they cannot lose on order. */
@media (max-width:760px){
  .topbar{padding:var(--s-4) var(--pad)}
  .ch{min-height:104svh; padding:var(--s-16) var(--pad) var(--s-12)}
  /* right-aligned compositions do not survive a narrow column */
  .ch[data-align="br"],.ch[data-align="tr"]{justify-items:start; text-align:left}
  .ch[data-align="br"] .frag-line,.ch[data-align="tr"] .frag-line{margin-left:0}
  .big{font-size:clamp(34px,11vw,64px)}
  .mid{font-size:clamp(26px,7.4vw,40px)}
  .frag-line{font-size:clamp(17px,4.6vw,24px); max-width:20ch}
  .body{font-size:15px; max-width:26ch}
  .frag{grid-template-columns:40px 1fr; row-gap:2px}
  .frag-state{grid-column:2}
  #gateKey,#crossKey{width:104px; height:104px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
}
