/* The fonts are named here instead of through Fontshare's stylesheet: a stylesheet
   blocks the first paint, so a slow font host would leave the whole page blank. */
@font-face { font-family: "General Sans"; font-weight: 400; font-style: normal; font-display: swap; src: url("https://cdn.fontshare.com/wf/MFQT7HFGCR2L5ULQTW6YXYZXXHMPKLJ3/YWQ244D6TACUX5JBKATPOW5I5MGJ3G73/7YY3ZAAE3TRV2LANYOLXNHTPHLXVWTKH.woff2") format("woff2"); }
@font-face { font-family: "General Sans"; font-weight: 500; font-style: normal; font-display: swap; src: url("https://cdn.fontshare.com/wf/3RZHWSNONLLWJK3RLPEKUZOMM56GO4LJ/BPDRY7AHVI3MCDXXVXTQQ76H3UXA63S3/SB2OEB6IKZPRR6JT4GFJ2TFT6HBB6AZN.woff2") format("woff2"); }
@font-face { font-family: "General Sans"; font-weight: 600; font-style: normal; font-display: swap; src: url("https://cdn.fontshare.com/wf/K46YRH762FH3QJ25IQM3VAXAKCHEXXW4/ISLWQPUZHZF33LRIOTBMFOJL57GBGQ4B/3ZLMEXZEQPLTEPMHTQDAUXP5ZZXCZAEN.woff2") format("woff2"); }
@font-face { font-family: "Zodiak"; font-weight: 300; font-style: normal; font-display: swap; src: url("https://cdn.fontshare.com/wf/IF5ZIT3FMSFNWCWOG7ZASDFHEMLSIUEE/OMOWAZNE73OKOHTUSHA6P7FH44MIVQTO/UREX64UV4XADQWU6EF6JRA5XVIEJPRP4.woff2") format("woff2"); }
@font-face { font-family: "Zodiak"; font-weight: 300; font-style: italic; font-display: swap; src: url("https://cdn.fontshare.com/wf/DLIOQN7BAIDF52NEOLWMG25TF2G4E5BG/2SBXS5PNCQ52C2STGTCLTGD7FAKWZYER/ZRX2TEYEJEWBO7BARVINFDFGSQVQCGX6.woff2") format("woff2"); }
@font-face { font-family: "Zodiak"; font-weight: 400; font-style: normal; font-display: swap; src: url("https://cdn.fontshare.com/wf/ECUEQQ5BLZLFJS3PPLWOEEVS7SQONQMH/WNTXEMDDVWUVWDURRKDXCJC6G7TMP277/TBWKTFSYABV4KN4GNIJMAOQUOTYBUWB3.woff2") format("woff2"); }
@font-face { font-family: "Zodiak"; font-weight: 400; font-style: italic; font-display: swap; src: url("https://cdn.fontshare.com/wf/YFLZBMMI3DYRSZHBNXVNB72OCINBINIT/AJUISU4RPSUOUSQPHGNMFKZ4M6TTQGWF/HUKQ64PZXOIVT5LHOHNUDCYHXBK5OR45.woff2") format("woff2"); }

/* Kefy Studio: the shell every page shares, the index page, and its calm
   fallback.

   The bare styles for the index are the calm stacked page, so it reads with no
   script at all. `html.fly`, set before first paint, turns on the flight:
   the words leave the document flow and hang over the canvas. */

/* ---------------------------------------------------------------- tokens -- */
:root {
  --deep: #040926;
  --night: #071238;
  --kefy: #2B5BD7;
  --ink: #FFFFFF;
  --ink-2: rgba(255,255,255,.72);
  --line: rgba(255,255,255,.28);
  --fog: #E4E6FB;
  --fog-ink: #10163A;
  --sans: "General Sans", "Helvetica Neue", Arial, sans-serif;
  --serif: "Zodiak", Georgia, serif;
  --gutter: clamp(16px, 2.5vw, 36px);
  --ease: cubic-bezier(.2,.7,.2,1);

  --nav-h: 82px;
  --foot-h: 94px;
  --glass: rgba(7, 18, 56, .52);
  --glass-edge: rgba(255, 255, 255, .14);

  /* Unseen's rem: its whole shell hangs off this, so the shell scales as one piece. */
  --ui-size: clamp(14px, 1vw, 19px);
  --hit: calc(var(--ui-size) * 3.7);          /* a round button's target: 53px at 1440 */
  --disc: calc(var(--ui-size) * 2.7);         /* the disc it draws: 39px at 1440 */
  --disc-in: calc(var(--ui-size) * .5);       /* the gap between the two */

  /* The shell's own ink, which flips when the flight reaches the pale fog. */
  --ui: var(--ink);
  --ui-2: var(--ink-2);
  --ui-edge: rgba(255, 255, 255, .78);
  --ui-on: var(--fog-ink);

  /* The small viewport, which is what the engine measures on a phone at rest. */
  --vh: 1vh;
}
@supports (height: 1svh) {
  :root { --vh: 1svh; }
}
:root[data-tone="pale"] {
  --ui: var(--fog-ink);
  --ui-2: rgba(16, 22, 58, .72);
  --ui-edge: rgba(16, 22, 58, .78);
  --ui-on: var(--ink);
  --glass: rgba(16, 22, 58, .88);
}

/* ------------------------------------------------------------------ base -- */
*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--deep);
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--deep);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -.012em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, p { margin: 0; }
img, svg { display: block; }
button { font: inherit; letter-spacing: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.arrow {
  width: 11px;
  height: 11px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  transition: transform .2s var(--ease);
}

/* The scroll is the timeline, so a scrollbar would only be a second, worse one. */
html.fly:is([data-page="index"], [data-page="project"]) { scrollbar-width: none; }
html.fly:is([data-page="index"], [data-page="project"])::-webkit-scrollbar { display: none; }

/* ----------------------------------------------------------- canvas, veil -- */
#stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
}
html:not(.fly) #stage { display: none; }

/* Dims the canvas for the moment a page swaps. The canvas never stops under it. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  background: var(--deep);
  opacity: 0;
  pointer-events: none;
  transition: opacity .42s var(--ease);
}
html.is-leaving body::before {
  opacity: 1;
  transition-duration: .22s;
}

#page {
  position: relative;
  z-index: 2;
  outline: 0;
  transition: opacity .42s var(--ease);
}
html.is-leaving #page {
  opacity: 0;
  transition-duration: .22s;
}

/* ------------------------------------------------------------------- nav -- */
.nav {
  position: fixed;
  z-index: 10;
  inset: 0 0 auto;
  display: flex;
  align-items: center;
  gap: calc(var(--ui-size) * .75);
  height: var(--nav-h);
  padding: 0 var(--gutter);
  color: var(--ui);
  pointer-events: none;
  transition: opacity .8s var(--ease), color .25s var(--ease);
}
.nav > * { pointer-events: auto; }

.mark {
  display: inline-flex;
  align-items: baseline;
  margin-right: auto;
  color: inherit;
  font-size: clamp(24px, 1.85vw, 32px);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -.04em;
  text-decoration: none;
}
.mark em {
  margin-left: .1em;
  font-family: var(--serif);
  font-style: normal;
  font-weight: 300;
  letter-spacing: -.025em;
}

.tabs { display: flex; gap: calc(var(--ui-size) * 1.5); }
.tabs a {
  position: relative;
  padding: 3px 0;
  color: inherit;
  font-size: calc(var(--ui-size) * 1.2);
  font-weight: 400;
  text-decoration: none;
}
.tabs a::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .22s var(--ease);
}

/* The whole button stays the target. What shows is the smaller disc inside it. */
.menu-btn {
  position: relative;
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ui-size) * .26);
  width: var(--hit);
  height: var(--hit);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ui-on);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color .25s var(--ease);
}
.menu-btn::before {
  content: "";
  position: absolute;
  inset: var(--disc-in);
  border-radius: 50%;
  background: var(--ui);
  transition: background-color .25s var(--ease);
}
.menu-btn i {
  position: relative;
  width: calc(var(--ui-size) * .27);
  height: calc(var(--ui-size) * .27);
  border-radius: 50%;
  background: currentColor;
  transition: transform .2s var(--ease);
}
.menu-btn:focus-visible {
  outline-color: var(--ui);
  outline-offset: calc(3px - var(--disc-in));   /* around the disc, not the target */
}

/* ----------------------------------------------------------------- pills -- */
.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: calc(var(--ui-size) * 2.4);
  padding: 0 calc(var(--ui-size) * 1.4);
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: var(--fog-ink);
  font-family: var(--sans);
  font-size: calc(var(--ui-size) * 1.05);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -.012em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .2s var(--ease), background-color .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.pill:focus-visible { outline-color: var(--ink); }

.pill--line {
  border-color: var(--ui-edge);
  background: transparent;
  color: var(--ui);
}
.pill--line:focus-visible { outline-color: var(--ui); }

/* ------------------------------------------------------------------ foot -- */
.foot {
  position: fixed;
  z-index: 10;
  inset: auto 0 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 var(--gutter) 20px;
  color: var(--ui);
  pointer-events: none;
  transition: opacity .8s var(--ease), color .25s var(--ease);
}
.foot > * { pointer-events: auto; }
.foot small {
  align-self: flex-end;
  margin-left: auto;
  margin-bottom: var(--disc-in);    /* it sits on the disc's bottom edge, not its middle */
  font-size: var(--ui-size);
  font-weight: 400;
  letter-spacing: -.005em;
}

/* Unseen thins its footer page by page, and only the Index keeps everything. Read off
   #page rather than <html>, so a direct load is right before any script has run. */
#page:is([data-page="projects"], [data-page="project"]) ~ .foot > :not(.sound),
#page:is([data-page="contact"], [data-page="world"]) ~ .foot .pill,
#page[data-page="world"] ~ .foot .world-link { display: none; }

/* Dark glass on purpose: it reads the same on the blue night and the pale fog.
   The disc sits on the gutter, under the wordmark, and its target hangs outside. */
.sound {
  position: relative;
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: .11em;
  width: var(--hit);
  height: var(--hit);
  margin-left: calc(-1 * var(--disc-in));
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink);
  font-size: var(--ui-size);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sound::before {
  content: "";
  position: absolute;
  inset: var(--disc-in);
  border: 1px solid var(--glass-edge);
  border-radius: 50%;
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  transition: background-color .2s var(--ease);
}
.sound:focus-visible {
  outline-color: var(--ui);
  outline-offset: calc(3px - var(--disc-in));
}
.sound i {
  position: relative;
  width: .1em;
  height: .97em;
  border-radius: 1px;
  background: currentColor;
  transform: scaleY(.12);
  transition: transform .25s var(--ease);
}
.sound[aria-pressed="true"] i {
  animation: sound-bar var(--beat) ease-in-out var(--late) infinite alternate;
}
/* No two bars keep the same time, or it would read as a meter. */
.sound i:nth-child(1) { --peak: .45; --beat: 1.3s; --late: -.3s; }
.sound i:nth-child(2) { --peak: .8;  --beat: 1.7s; --late: -.9s; }
.sound i:nth-child(3) { --peak: 1;   --beat: 1.1s; --late: -.5s; }
.sound i:nth-child(4) { --peak: .7;  --beat: 1.9s; --late: -1.2s; }
.sound i:nth-child(5) { --peak: .4;  --beat: 1.4s; --late: -.7s; }
@keyframes sound-bar {
  from { transform: scaleY(.18); }
  to { transform: scaleY(var(--peak, 1)); }
}

.world-link {
  position: absolute;
  left: 50%;
  bottom: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--hit);               /* the same line as the sound button */
  color: inherit;
  font-size: max(12px, calc(var(--ui-size) * .8));
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;
  text-decoration: none;
  transform: translateX(-50%);
}
.globe {
  display: inline-grid;
  place-items: center;
  flex: none;
  vertical-align: baseline;
}
.globe::before {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1'%3E%3Ccircle cx='12' cy='12' r='10.5'/%3E%3Cellipse cx='12' cy='12' rx='4.9' ry='10.5'/%3E%3Cpath d='M12 1.5v21M1.5 12h21'/%3E%3Cpath d='M3.1 6.6c2.5 1.5 5.6 2.2 8.9 2.2s6.4-.7 8.9-2.2M3.1 17.4c2.5-1.5 5.6-2.2 8.9-2.2s6.4.7 8.9 2.2'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1'%3E%3Ccircle cx='12' cy='12' r='10.5'/%3E%3Cellipse cx='12' cy='12' rx='4.9' ry='10.5'/%3E%3Cpath d='M12 1.5v21M1.5 12h21'/%3E%3Cpath d='M3.1 6.6c2.5 1.5 5.6 2.2 8.9 2.2s6.4-.7 8.9-2.2M3.1 17.4c2.5-1.5 5.6-2.2 8.9-2.2s6.4.7 8.9 2.2'/%3E%3C/svg%3E") center / contain no-repeat;
}
.world-link .globe {
  width: var(--disc);
  height: var(--disc);
  padding: calc(var(--disc) * .2);
  border: 1px solid var(--glass-edge);
  border-radius: 50%;
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  color: var(--ink);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.world-link:focus-visible { outline-color: var(--ui); outline-offset: 5px; }

/* Only where a pointer can really hover: on a phone these would stick after a tap,
   and the shell outlives the page it was tapped on. */
@media (hover: hover) {
  .tabs a:hover::after { transform: scaleX(1); }
  .menu-btn:hover i:first-child { transform: translateX(-2px); }
  .menu-btn:hover i:nth-child(2) { transform: translateX(2px); }
  .pill:hover { background: var(--fog); border-color: var(--fog); }
  .pill:hover .arrow { transform: translate(1.5px, 1.5px); }
  .pill--line:hover { border-color: var(--ui); background: var(--ui); color: var(--ui-on); }
  .sound:hover::before { background: rgba(7, 18, 56, .72); }
  .world-link:hover .globe { background: var(--ink); color: var(--fog-ink); }
}

/* ------------------------------------------------------------------ menu -- */
html.menu-open { overflow: hidden; }

#menu {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0 var(--gutter) 26px;
  overflow: auto;
  overscroll-behavior: contain;
  border: 0;
  outline: 0;
  background: var(--fog);
  color: var(--fog-ink);
  font-family: var(--sans);
  opacity: 0;
  transition: opacity .24s var(--ease);
}
#menu[open] {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: 1fr auto;
  align-items: end;
  gap: 24px;
}
#menu.is-open { opacity: 1; }
#menu::backdrop { background: transparent; }
#menu a { color: inherit; text-decoration: none; }
#menu :focus-visible { outline-color: var(--fog-ink); }

#menu nav {
  --size: clamp(52px, min(13.5vh, 16.5vw), 96px);
  grid-column: 1 / -1;
  align-self: center;
  padding-top: var(--nav-h);
}
#menu nav a {
  display: table;
  font-family: var(--serif);
  font-size: var(--size);
  font-weight: 300;
  line-height: 1.03;
  letter-spacing: -.03em;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .24s var(--ease), transform .24s var(--ease), color .18s var(--ease);
}
#menu.is-open nav a { opacity: 1; transform: none; }
#menu.is-open nav a:nth-child(2) { transition-delay: 30ms, 30ms, 0s; }
#menu.is-open nav a:nth-child(3) { transition-delay: 60ms, 60ms, 0s; }
#menu.is-open nav a:nth-child(4) { transition-delay: 90ms, 90ms, 0s; }

/* The numeral hangs from the top of the capitals, as a footnote mark would. */
#menu nav small {
  display: inline-block;
  width: 1.7em;
  margin-top: calc(var(--size) * .17);
  font-family: var(--sans);
  font-size: calc(var(--ui-size) * 1.3);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -.01em;
  vertical-align: top;
}

/* Hover and the page you are on share one look: the sans, faded, underlined.
   On AA grounds it fades to 3.7:1, the floor for type this large. */
#menu nav a:hover,
#menu nav a[aria-current="page"] {
  color: rgba(16, 22, 58, .55);
  font-family: var(--sans);
  font-weight: 400;
  letter-spacing: -.045em;
  text-decoration: underline;
  text-decoration-thickness: .045em;
  text-underline-offset: .1em;
}
#menu nav a:hover small,
#menu nav a[aria-current="page"] small { color: var(--fog-ink); }

#menu nav .globe {
  width: .36em;
  height: .36em;
  margin-left: .22em;
  color: var(--fog-ink);
}

#menu > p {
  display: grid;
  gap: 3px;
}
#menu > p,
#menu > a {
  font-size: var(--ui-size);
  font-weight: 400;
}
#menu > p a { justify-self: start; }
#menu > a {
  justify-self: end;
  align-self: end;
}
#menu > p a:hover,
#menu > a:hover {
  text-decoration: underline;
  text-underline-offset: .2em;
}

/* Lands on the menu button it replaces: the same target and the same disc. Its strokes
   take both pseudo-elements, so here the disc is the background, held to the content. */
#menu > button {
  position: fixed;
  top: calc((var(--nav-h) - var(--hit)) / 2);
  right: var(--gutter);
  width: var(--hit);
  height: var(--hit);
  padding: var(--disc-in);
  border: 0;
  border-radius: 50%;
  background: var(--fog-ink) content-box;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#menu > button:focus-visible { outline-offset: calc(3px - var(--disc-in)); }
#menu > button::before,
#menu > button::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 30%;
  height: 1.5px;
  margin: -.75px 0 0 -15%;
  background: currentColor;
  transform: rotate(45deg);
  transition: transform .2s var(--ease);
}
#menu > button::after { transform: rotate(-45deg); }
#menu > button:hover::before { transform: rotate(135deg); }
#menu > button:hover::after { transform: rotate(45deg); }

/* From here up it is Unseen's right-hand panel, with the world still there beside it.
   closeMenu in main.js reads its wait from this transition, so the two stay in step. */
@media (min-width: 861px) {
  #menu {
    inset: 0 0 0 auto;
    width: 41vw;
    min-width: 520px;
    padding: 0 var(--gutter) var(--gutter) 6.25vw;
    opacity: 1;
    transform: translateX(100%);
    transition: transform .5s var(--ease);
  }
  #menu.is-open { transform: none; }
  #menu nav { --size: min(calc(var(--ui-size) * 6.25), 13.5vh); }
  #menu::backdrop {
    background: rgba(4, 9, 38, .28);
    opacity: 0;
    transition: opacity .5s var(--ease);
  }
  #menu.is-open::backdrop { opacity: 1; }
}

/* ------------------------------------------- the calm page: index, no flight -- */
html[data-page="index"]:not(.fly) .nav { position: absolute; }
html[data-page="index"]:not(.fly) .foot {
  position: static;
  flex-wrap: wrap;
  padding-top: 24px;
  background: var(--deep);
}
html[data-page="index"]:not(.fly) .world-link {
  position: static;
  margin: 0 auto;
  transform: none;
}
html[data-page="index"]:not(.fly) .foot small { margin-left: 0; }

/* With script off the buttons have nothing to do, so the tabs stand in for them. */
html:not(.fly):not(.calm) .sound,
html:not(.fly):not(.calm) .menu-btn { display: none; }

/* #page must not stack here, or the ring's black could not screen into the blue. */
html[data-page="index"]:not(.fly) #page { z-index: auto; }

.gate {
  padding: calc(var(--nav-h) + 12px) var(--gutter) clamp(40px, 7vw, 88px);
  text-align: center;
}
.gate .still {
  width: min(100%, 860px);
  height: auto;
  margin: 0 auto;
  mix-blend-mode: screen;
  -webkit-mask-image: none;
  mask-image: none;
}
.gate-copy { margin-top: -2vw; }
.gate-name { font-size: 16px; }
.gate-line {
  max-width: 34ch;
  margin: 6px auto 0;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.28;
  text-wrap: balance;
}
.gate .pill,
.gate-quiet { display: none; }

.beat {
  padding: 0 var(--gutter) clamp(40px, 7vw, 96px);
  text-align: center;
}
/* Feathered top and bottom, so each picture dissolves into the page's blue. */
.still {
  width: calc(100% + 2 * var(--gutter));
  max-width: none;
  height: auto;
  max-height: 92vh;
  margin: 0 calc(-1 * var(--gutter)) clamp(24px, 4vw, 48px);
  object-fit: cover;
  -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, .55) 5%, #000 13%, #000 87%, rgba(0, 0, 0, .55) 95%, transparent);
  mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, .55) 5%, #000 13%, #000 87%, rgba(0, 0, 0, .55) 95%, transparent);
}

.beat--line p {
  max-width: 34ch;
  margin: 0 auto;
  font-size: 19px;
  line-height: 1.3;
  text-wrap: balance;
}

/* The end of the page. With no laptop to sit on, it is plain type on the blue. */
#laptop-page h1 {
  font-family: var(--serif);
  font-size: clamp(36px, 4.9vw, 72px);
  font-weight: 300;
  line-height: 1.06;
  letter-spacing: -.024em;
}
.laptop-line { display: none; }     /* the gate already says this */
.laptop-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 26px;
}

/* ------------------------------------------------------------ the flight -- */
html.fly #track { width: 1px; pointer-events: none; }
html.fly .gate { display: none; }
html.fly .still { display: none; }

html.fly .beat {
  position: fixed;
  left: var(--gutter);
  right: var(--gutter);
  padding: 0;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 0 26px rgba(4, 9, 38, .46);
}
html.fly .beat.is-on a { pointer-events: auto; }

/* Under the shop, and on a short window, still clear of the bar at the bottom. */
html.fly .beat--go {
  top: min(80.5%, calc(100% - var(--foot-h) - 56px));
  text-shadow: none;
}
html.fly .beat--go .pill { animation: arrive .9s var(--ease) backwards; }
@keyframes arrive {
  from { opacity: 0; transform: translateY(8px); }
}

html.fly .beat--line { bottom: calc(var(--foot-h) + 1vh); }
html.fly .beat--line p { max-width: none; font-size: 18px; }

/* A small real page on the laptop's own screen. main.js fits it to the screen each
   frame and sets its font-size, so everything here is in em and it arrives with
   the camera. No background: the screen is the page. */
html.fly #laptop-page {
  top: 0;
  right: auto;
  display: grid;
  align-content: center;
  justify-items: center;
  color: var(--fog-ink);
  text-shadow: none;
}
html.fly #laptop-page h1 { font-size: 2.5em; }

/* The frame has its own pair of pills, so the bar's one steps aside while it shows.
   Hidden as well as faded, or a keyboard could land on a pill nobody can see. */
html:has(#laptop-page.is-on) .foot .pill {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s var(--ease), visibility 0s .2s;
}

html.fly .laptop-line {
  display: block;
  max-width: 30em;
  margin-top: .75em;
  color: rgba(16, 22, 58, .72);
  font-size: .92em;
  line-height: 1.3;
  text-wrap: balance;
}

html.fly .laptop-links { gap: .55em; margin-top: 1.2em; }
html.fly #laptop-page .pill {
  gap: .55em;
  min-height: 2.75em;
  padding: 0 1.3em;
  border-color: var(--fog-ink);
  background: var(--fog-ink);
  color: var(--ink);
  font-size: max(12px, .82em);
}
html.fly #laptop-page .pill--line {
  background: transparent;
  color: var(--fog-ink);
}
html.fly #laptop-page :focus-visible { outline-color: var(--fog-ink); }
@media (hover: hover) {
  html.fly #laptop-page .pill:hover { border-color: var(--kefy); background: var(--kefy); color: var(--ink); }
}

/* ------------------------------------------------------------------ gate -- */
html.gating,
html.gating body { background: #000; }

html.gating .nav,
html.gating .foot {
  opacity: 0;
  visibility: hidden;
}
html.gating .beat { display: none; }
html.gating #laptop-page a { visibility: hidden; }

html.gating .gate {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 5;
  padding: 0;
}
/* Sits just under the ring. Ring's lower rim is 75.5% down while the picture
   fits by height, then rides lower on wide windows as the picture crops; the
   min() keeps the block on screen when a short window would push it off. */
html.gating .gate-copy {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: min(
    calc(max(75.5 * var(--vh), 50 * var(--vh) + 14.9vw) + 12px),
    calc(100 * var(--vh) - 172px)
  );
  margin: 0;
}
html.gating .gate .pill {
  display: inline-flex;
  margin-top: 14px;
}
html.gating .gate-quiet {
  display: block;
  position: absolute;
  left: 50%;
  bottom: 22px;
  padding: 4px 0 2px;
  border: 0;
  border-bottom: 1px solid currentColor;
  background: none;
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: .01em;
  white-space: nowrap;
  cursor: pointer;
  transform: translateX(-50%);
  transition: opacity .2s var(--ease);
}

html.gating .gate-copy,
html.gating .gate-quiet {
  opacity: 0;
  transition: opacity 1.1s var(--ease) .35s;
}
html.gate-up .gate-copy,
html.gate-up .gate-quiet { opacity: 1; }
html.gating.entering .gate-copy,
html.gating.entering .gate-quiet {
  opacity: 0;
  pointer-events: none;
  transition: opacity .35s var(--ease);
}

/* ---------------------------------------------------------------- phones -- */
@media (max-width: 860px) {
  :root { --nav-h: 72px; --foot-h: 84px; }

  .tabs { display: none; }
  html:not(.fly):not(.calm) .tabs { display: flex; gap: 18px; }
  html:not(.fly):not(.calm) .tabs a { padding: 13px 0; font-size: 15px; }

  /* Unseen's type with a thumb's target: the padding shows nothing but can be tapped. */
  .mark { padding: 10px 0; }
  .pill { min-height: 44px; }

  .foot { gap: 8px; padding-bottom: 16px; }
  .foot small { display: none; }
  .world-link { display: none; }      /* it stays in the menu, as Unseen's does */

  html.fly #laptop-page .pill { min-height: 2.95em; font-size: 1em; }

  /* Sits in the dark under the ring, so the target can reach well past the type. */
  html.gating .gate-quiet::after {
    content: "";
    position: absolute;
    inset: -13px -6px;
  }

  #menu nav small { font-size: 14px; }
  #menu > p { gap: 0; }
  #menu > p a,
  #menu > a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* A short window has no room under the ring, so its lower rim sinks into the dark
   and the words sit where it was. */
@media (max-height: 640px) {
  html.gating .gate::before {
    content: "";
    position: absolute;
    inset: 54% 0 0;
    background: linear-gradient(to bottom, transparent, #000 46%);
  }
  html.gating .gate-line { max-width: none; }
  html.gating .gate .pill { margin-top: 8px; }
}

/* -------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
  #menu::backdrop { transition: none !important; }    /* the * above does not reach it */
  .sound[aria-pressed="true"] i { transform: scaleY(var(--peak, 1)); }
}
