body {
  margin: 0;
  background-color: #a2a7af;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* ===== intro animation (from test-text/text-test-4.html) ===== */

#intro {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 80px 20px 40px;
  max-width: 1600px;
  margin: 0 auto;
  box-sizing: border-box;
  font-family: sans-serif;
  position: relative;
  left: 20px;
  top: -20px;
}

#text {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.17em;
  font-size: clamp(9.75px, 3.75vw, 39.75px);
  color: #6e394d;
  text-align: center;
  line-height: 1.1;
}

/* title shown under the grid only on a repeat visit (the fixed return-visit image) --
   same font family as the name text above (#text) */
.grid-title {
  display: none;
  font-family: sans-serif;
  color: #fff;
  text-align: center;
  font-size: 16px;
  margin: 0; /* space above is set by JS (GRID_TITLE_GAP in index.html), measured from the grid */
}

.grid-title .piece-name {
  font-style: italic;
  font-size: 17.6px;
}

/* phones held upright: smaller text, so the title has a better chance of fitting on one line */
@media (orientation: portrait) and (max-width: 700px) {
  .grid-title {
    font-size: 14px;
  }

  .grid-title .piece-name {
    font-size: 15.4px;
  }
}

.big {
  font-size: clamp(24px, 7vw, 95.5px);
  line-height: 0.5;
}

.small {
  clip-path: inset(0 0 100% 0);
  animation: wipeDown 1s ease-out forwards;
  animation-delay: 1.5s;
}

.small.k {
  clip-path: inset(0 100% 0 0);
  animation: wipeRight 1s ease-out forwards;
  animation-delay: 2.5s;
}

.reveal-slot {
  position: relative;
}

.okart {
  display: flex;
  align-items: flex-start;
  gap: 0.17em;
  animation: fadeOut 1s ease forwards;
  animation-delay: 0.5s;
}

.reveal-slot .small.k {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  letter-spacing: 0.39em;
}

@keyframes wipeDown {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0% 0); }
}

@keyframes wipeRight {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0% 0 0); }
}

@keyframes fadeOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ===== menu-bar / menu-toggle: page-specific pieces (shared rules live in style.css) ===== */

#menu-bar {
  background: #a2a7af;
  padding-left: 20px;
  font-size: 16px;
}

#menu-bar::before {
  content: "";
}

#menu-toggle {
  opacity: 0;
  pointer-events: none;
  animation: menuArrive 0.6s ease forwards;
  animation-delay: 3.5s;
}

@keyframes menuArrive {
  from { opacity: 0; pointer-events: none; }
  to   { opacity: 1; pointer-events: auto; }
}

/* ===== home layout (title + first image) ===== */

.home {
  display: flex;
  flex-direction: column;
  position: relative;
  /* #intro is nudged 20px right (left: 20px), so its empty right edge stuck out 20px past
     the screen -- making the whole page 20px too wide. On iPhone the page could then slide
     sideways, and the menu (pinned to the right edge) jumped and flickered. Trim it off. */
  overflow-x: clip;
}

@media (orientation: landscape) {
  .home {
    flex-direction: row;
    align-items: center;
  }

  .home #intro {
    width: 100%;
  }
}

.home #intro {
  margin-left: 0;
  margin-right: 0;
}

/* invisible box that constrains and positions the grid of lines;
   top/height are set by JS (top of .home through the "e" of "onkle");
   left/width stay fixed here */
.grid-box {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.75s ease;
}

/* line 1: horizontal, through the "a" in "aurice" */
.onkle-line {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: #fff;
  clip-path: inset(0 100% 0 0);
  animation: wipeRight 1s ease-out forwards;
  animation-delay: 2.5s;
}

/* 5 more horizontal lines, through u / r / i / c / e of "aurice", plus 5 further lines
   below "e" continuing the same spacing; top and animation-delay set per-line by JS */
.h-line,
.h-line-extra {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: #fff;
  clip-path: inset(0 100% 0 0);
  animation: wipeRight 1s ease-out forwards;
}

/* image that fades up in the middle of the grid once it finishes shrinking;
   position/size set by JS to fit inside the frame-box with margin from its edges */
.grid-fade-image {
  position: absolute;
  object-fit: contain;
  opacity: 0;
  transition: opacity 2s ease;
  pointer-events: none;
}

.grid-fade-image.revealed {
  opacity: 0.66;
}

/* frame-box: starts full-page size, shrinks down to the grid-defined rectangle
   (top-left: a-line x one-right-of-e vline; bottom-right: e-line x near-hamburger vline) */
.frame-box {
  position: absolute;
  border: none;
  box-sizing: border-box;
  transition: top 1.75s ease, left 1.75s ease, width 1.75s ease, height 1.75s ease;
}

/* dot placed on a grid crossing (return visit); size and position set by JS */
.grid-dot {
  position: absolute;
  border-radius: 50%;
  background: #fff;
  opacity: 0; /* fades up when JS adds .shown; fade speed set by DOT_FADE_MS in index.html */
}

.grid-dot.shown {
  opacity: 0.8;
}

/* vertical lines: one anchored through the "e" in "onkle", the rest generated by JS
   at the same spacing as the horizontal lines, filling the box edge to edge */
.v-line {
  position: absolute;
  top: 0;
  width: 1px;
  background: #fff;
  clip-path: inset(0 0 100% 0);
  animation: wipeDown 1s ease-out forwards;
}

.home #intro {
  position: relative;
  z-index: 1;
}

/* ===== content box below the title/grid animation ===== */

.content-box {
  border: 3px solid rgba(255, 255, 255, 0.9); /* white at 90% opacity */
  border-radius: 0;
  margin: 100px 20px 30px; /* top, left and right, bottom */
  box-sizing: border-box;
  opacity: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 200px;
}

/* phones in landscape (short screens): give the blank box a taller floor,
   scaled to the viewport height, instead of the flat 200px */
@media (orientation: landscape) and (max-height: 1050px) and (hover: none) and (pointer: coarse) {
  .content-box {
    min-height: 75vh;
  }
}

.content-box p {
  font-family: sans-serif;
  font-size: 24px;
  color: rgba(255, 255, 255, 0.9); /* white at 90% opacity, same as the box border */
  text-align: center;
  margin: 0;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.content-box p.revealed {
  opacity: 1;
}

/* phones held upright: "this space left intentionally blank" scaled down by the same amount
   as the grid title (24px -> 21px), so the two keep the same size relationship as on a computer.
   Has to come after the .content-box p rule above, or that rule's 24px would win. */
@media (orientation: portrait) and (max-width: 700px) {
  .content-box p {
    font-size: 21px;
  }
}

.content-box.revealed {
  animation: fadeIn 0.75s ease-out forwards;
}

/* ===== skip-intro: repeat visit this session, jump every entrance animation
   straight to its finished state instead of playing it ===== */

html.skip-intro .small,
html.skip-intro .small.k {
  animation: none;
  clip-path: inset(0 0 0 0);
}

html.skip-intro .okart {
  animation: none;
  opacity: 0;
}

html.skip-intro #menu-toggle {
  animation: none;
  opacity: 1;
  pointer-events: auto;
}

html.skip-intro .onkle-line,
html.skip-intro .h-line,
html.skip-intro .h-line-extra,
html.skip-intro .v-line {
  animation: none;
  clip-path: inset(0 0 0 0);
}

html.skip-intro .frame-box,
html.skip-intro .grid-box {
  transition: none;
}

html.skip-intro .content-box.revealed {
  animation: none;
  opacity: 1;
}

html.skip-intro .content-box p {
  transition: none;
}

html.skip-intro .grid-fade-image,
html.skip-intro .grid-fade-image.revealed {
  transition: none;
}
