/**
 * Layout Styles
 * 
 * Illustration positioned bottom-left. Text columns aligned to top of illustration,
 * with 40px offset from gridlines. Implements the print-inspired, framed page aesthetic.
 */

/* Page Frame - Dark green border wrapper */
.page-frame {
  --line-1: 25%;
  --line-2: 50%;
  --line-3: 75%;
  position: relative;
  min-height: 100vh;
  border: var(--border-width) solid var(--color-border);
  background-color: var(--color-bg-page);
  padding: var(--content-padding);
}

/* Decorative gridlines: hairlines at the frame's --line-* positions (the
   writing transition animates those). Real elements rather than frame
   backgrounds, so they can be ruled in with a transform (base.css). */
.gridlines {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.gridline {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--line-1);
  width: 1px;
  background: var(--color-gridline);
  transform-origin: 50% 0;
}

.gridline--2 {
  left: var(--line-2);
}

.gridline--3 {
  left: var(--line-3);
}

/* Page Content - Contains title/logo; above illustration when window is short.
   Owns the name's colour so it can cross-fade between pages (history.css mutes
   it). The recolour is the biggest change on screen, so it takes its time: it
   is still settling as the other page's content arrives. */
.page-content {
  position: relative;
  z-index: 2;
  color: var(--color-name-ink);
  transition: color var(--dur-5) var(--ease-in-out);
}

@media (prefers-reduced-motion: reduce) {
  .page-content {
    transition: none;
  }
}

/* Display Name - positioned 16px from top of page */
.display-name {
  font-family: var(--font-display);
  font-size: 128px;
  line-height: 60%;
  color: inherit;
  text-transform: lowercase;
  margin: 0;
  margin-top: 16px;
  font-weight: normal;
  letter-spacing: 0;
}

/* The name is split so it can be set line by line (and the e's one by one)
   on load. Splitting doesn't change the glyph positions: this face has no
   kerning across those pairs. */
.display-name .line {
  display: block;
}

.display-name .e {
  display: inline-block;
}

/* Text columns container - positioned to align with top of illustration */
.text-columns {
  position: absolute;
  top: 50vh; /* Fallback: middle of viewport, will be overridden by JavaScript */
  left: 0;
  right: 0;
  width: 100%;
  z-index: 2; /* Above illustration */
  /* Top position will be set by JavaScript to align with illustration top */
}

/* Text columns: positioned 40px to the right of gridlines */
.column {
  max-width: 192px;
  position: absolute;
  top: 0;
  white-space: normal;
  /* Figma body text: 14px / 20px line-height */
  line-height: 20px;
}

.column-bio {
  /* Gridline at 25% of page-frame width, text starts at 25% + 48px */
  left: calc(25% + 48px);
  width: auto;
}

.column-writing {
  /* Gridline at 50% of page-frame width, text starts at 50% + 48px */
  left: calc(50% + 48px);
  width: auto;
  /* "I do some writing & drawing & collecting" — one line on roomy desktops,
     but capped to its gridline zone so it wraps instead of overlapping "Come
     back soon" when the viewport is narrow. */
  max-width: calc(25% - 16px);
}

.column-soon {
  /* Gridline at 75% of page-frame width, text starts at 75% + 48px */
  left: calc(75% + 48px);
  width: auto;
}

.column p {
  /* Figma: 20px between paragraphs (one blank 20px line) */
  margin: 0 0 20px 0;
}

.column p:last-child {
  margin-bottom: 0;
}

/* Archive link ("writing & drawing & collecting") with trailing
   arrow-up-right icon. No gap: the arrow's 16x16 box has built-in left
   padding (the glyph is inset), which provides the visual spacing from the
   text. */
.archive-link,
.history-link {
  display: inline-flex;
  align-items: center;
  gap: 0;
}

.archive-link .arrow-icon,
.history-link .link-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* The outbound arrow says where it goes: a 1.5px nudge up and to the right,
   in fast with the fill and back slowly */
.archive-link .arrow-icon {
  transition: transform var(--dur-3) var(--ease-out);
}

/* The list icon previews the list: its three rules re-draw from the left,
   one after another */
.history-link .link-icon-rule {
  transform-box: fill-box;
  transform-origin: 0 50%;
}

@keyframes link-icon-rule-draw {
  from { transform: scaleX(0); }
  to { transform: none; }
}

@media (hover: hover) {
  .archive-link:hover .arrow-icon {
    transform: translate(1.5px, -1.5px);
    transition-duration: var(--dur-1);
  }

  .history-link:hover .link-icon-rule {
    animation: link-icon-rule-draw var(--dur-4) var(--ease-out-expo) both;
  }

  .history-link:hover .link-icon-rule:nth-of-type(3) {
    animation-delay: 40ms;
  }

  .history-link:hover .link-icon-rule:nth-of-type(4) {
    animation-delay: 80ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  .archive-link .arrow-icon,
  .archive-link:hover .arrow-icon {
    transform: none;
    transition: none;
  }

  .history-link:hover .link-icon-rule {
    animation: none;
  }
}

/* Illustration - absolutely positioned at bottom-left of page */
/* Fixed box (static image aspect 530×1480) so video hover doesn’t resize */
.illustration {
  position: absolute;
  bottom: var(--content-padding);
  left: var(--content-padding);
  z-index: 0;
  width: 172px;
  aspect-ratio: 530 / 1480;
  border: 1px solid var(--color-gridline);
  /* Blend target: the video's white background multiplies against this to
     become exactly the page color (multiply can only darken, never lighten) */
  background: var(--color-bg-page);
}

/* Fill container so image and video share same dimensions */
.illustration img,
.illustration video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Forward + reverse video layers stack in the same box; JS toggles opacity
   between them at matched frames (instant, seamless). */
.illustration video {
  position: absolute;
  inset: 0;
  /* Hovering plays him; there's nothing to click, so no pointer cursor */
  cursor: default;
  /* White video background multiplies down to the box's page-color background,
     guaranteeing the illustration never shows a background lighter than the page */
  mix-blend-mode: multiply;
}

/* Reverse (rewind) layer is hidden until the cursor leaves */
.illustration-rev {
  opacity: 0;
}

/* Peek illustration — a masked square in the top-right that expands on hover.
   The box is always the expanded size (the right half of the cream, from the
   center gridline, minus 12px of padding on each side), anchored 12px from
   the canvas edges; a clip-path shows only its top-right square until it
   opens. Clipping instead of resizing means no layout per frame, and since
   hit-testing follows the clip, the collapsed hover target is still just the
   square. In a window too short for that square it stops 12px above the
   cream's bottom instead: the clip hides the box but it still counts toward
   the page's scroll size, so it must never hang past the frame. */
.peek {
  --peek-expanded: min((100vw - var(--border-width) * 2) / 2 - 24px,
                       100vh - var(--border-width) * 2 - 24px);
  --peek-collapsed: 24px;
  position: absolute;
  top: 12px;
  right: 12px;
  width: var(--peek-expanded);
  height: var(--peek-expanded);
  overflow: hidden;
  z-index: 3; /* open, it lies over everything on the page (Figma) */
  cursor: pointer;
  clip-path: inset(0 0 calc(100% - var(--peek-collapsed)) calc(100% - var(--peek-collapsed)));
  /* clip-path = hover expand / pin (closing here); transform = on-load stamp
     (delayed, base.css). Folded into one transition so they don't clobber
     each other. */
  transform-origin: 100% 0;
  transition: clip-path var(--dur-4) var(--ease-in-out),
              transform var(--dur-4) var(--ease-out-expo) var(--d, 0s);
}

/* Expand on hover — after a short intent delay, so a cursor passing through
   the corner (on its way to the browser's own controls) doesn't pop it —
   unless just collapsed by a click while the cursor is still over it
   (suppressed until the pointer leaves). A pinned box stays expanded. */
.peek:hover:not(.is-suppressed),
.peek.is-pinned {
  clip-path: inset(0);
  transition: clip-path var(--dur-5) var(--ease-out-expo) 90ms,
              transform var(--dur-4) var(--ease-out-expo) var(--d, 0s);
}

/* Pinned (clicked open): the same 1px rule as the man illustration
   (bottom-left), drawn inside the box so nothing shifts when it appears */
.peek::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px var(--color-gridline);
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease-out);
}

.peek.is-pinned::after {
  opacity: 1;
}

/* Pinned, the no-background layer needs a ground of its own, or the columns
   it now reaches would show through the drawing. It comes on at once (the
   blue is still opaque while the layers cross-fade) and leaves only once the
   blue has faded back in. */
.peek::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--color-bg-page);
  opacity: 0;
  transition: opacity 0s linear var(--dur-3);
}

.peek.is-pinned::before {
  opacity: 1;
  transition: none;
}

/* Both illustration layers fill the box (object-contain), anchored to its
   top-right corner, so the collapsed square shows the (blue) top-right
   corner. As the mask opens the image settles from 1.06 into place, which
   gives the reveal depth instead of a flat wipe. */
.peek-img {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--peek-expanded);
  height: var(--peek-expanded);
  max-width: none; /* override global img { max-width: 100% } */
  object-fit: contain;
  pointer-events: none;
  transform: scale(1.06);
  transform-origin: 100% 0;
  transition: opacity var(--dur-3) var(--ease-out),
              transform var(--dur-4) var(--ease-in-out);
}

.peek:hover:not(.is-suppressed) .peek-img,
.peek.is-pinned .peek-img {
  transform: none;
  transition: opacity var(--dur-3) var(--ease-out),
              transform var(--dur-5) var(--ease-out-expo) 90ms;
}

/* Blue-background layer is the default; the no-background layer swaps in when
   pinned (Figma: 88% opacity). */
.peek-img-plain {
  opacity: 0;
}

.peek.is-pinned .peek-img-blue {
  opacity: 0;
}

.peek.is-pinned .peek-img-plain {
  opacity: 0.88;
}

@media (prefers-reduced-motion: reduce) {
  /* Opens and closes in one step; no settle */
  .peek-img,
  .peek:hover:not(.is-suppressed) .peek-img,
  .peek.is-pinned .peek-img {
    transform: none;
  }
}

/* Align text columns to top of illustration */
/* We need to calculate where the illustration top is and position text there */
/* Using JavaScript would be ideal, but we can approximate with CSS */
/* For now, we'll position text columns relative to a reference point */
/* The illustration height varies, so we'll need to adjust this */

/* Mobile grid field - hidden on desktop */
.grid-field {
  display: none;
}

/* Responsive: mobile layout with CSS Grid system */
@media (max-width: 768px) {
  .page-frame {
    /* Border reduces from 40px to 24px on all sides */
    border-width: 24px;
    background-color: var(--color-bg-page);
    padding: 0;
    min-height: 100vh;
    position: relative;
    /* Remove desktop gridlines - grid system handles alignment */
    background-image: none;
  }

  /* Mobile draws its own rails on .grid-field; the desktop gridlines would
     leak stray vertical lines at the quarter marks. */
  .gridlines {
    display: none;
  }

  /* Hide desktop layout elements on mobile */
  .page-content,
  .text-columns,
  .illustration,
  .peek {
    display: none;
  }
  
  /* Show and configure grid field */
  .grid-field {
    display: grid;
    /* 3 vertical zones defined by gridlines:
       Column line 1 = left margin edge
       Column line 2 = LEFT GRIDLINE (40px from left)
       Column line 3 = CENTER GRIDLINE (middle of two 1fr columns)
       Column line 4 = RIGHT GRIDLINE (40px from right)
       Column line 5 = right margin edge */
    grid-template-columns:
      40px          /* left margin to first gridline */
      1fr           /* column A (left gridline to center) */
      1fr           /* column B (center to right gridline) */
      40px;         /* right margin */
    
    row-gap: 0; /* per-block gaps set via margin-top (Figma rhythm is uneven) */
    padding: 0; /* critical: grid + gridlines must start at same edge */
    padding-top: 40px;
    padding-bottom: 80px;
    min-height: calc(100vh - 48px); /* Account for 24px border on each side */
    position: relative;
    
    /* Visual gridlines for alignment rails */
    background-image: 
      linear-gradient(to right, var(--color-gridline) 1px, transparent 1px),
      linear-gradient(to right, var(--color-gridline) 1px, transparent 1px),
      linear-gradient(to right, var(--color-gridline) 1px, transparent 1px);
    background-position: 
      40px 0,              /* Left gridline: 40px from left edge */
      50% 0,               /* Center gridline: 50% width */
      calc(100% - 40px) 0; /* Right gridline: 40px from right edge */
    background-size: 1px 100%;
    background-repeat: no-repeat;
  }
  
  /* Logo - large, spans full content width (left gridline to right gridline), top */
  .logo {
    grid-column: 2 / 4;
    grid-row: 1;
  }

  .logo .logo-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
  }

  /* Intro text (bio) - right column (center gridline to right gridline), under logo */
  .intro-text {
    grid-column: 3 / 4;
    grid-row: 2;
    margin-top: 40px; /* Figma gap: logo -> bio */
  }
  
  .intro-text p {
    margin: 0 0 20px 0;
    white-space: normal;
  }
  
  .intro-text p:last-child {
    margin-bottom: 0;
  }
  
  /* Illustration - enlarged: starts at the left gridline and extends past
     the center gridline (Figma: 198px of the 345px cream). Spans the content
     area; width set on the img so its right edge lands at ~cream-x 238. */
  .illustration-mobile {
    grid-column: 2 / 4;
    grid-row: 3;
    margin-top: 47px; /* Figma gap: bio bottom -> illustration top */
  }

  /* Left edge sits on the left gridline (which serves as the left border),
     so only top/right/bottom are drawn (Figma) */
  .illustration-mobile img {
    width: 74.7%; /* ~198px of the 265px content area */
    height: auto;
    display: block;
    border: 1px solid var(--color-gridline);
    border-left: none;
  }

  /* Lower text - right column (center gridline to right gridline), bottom */
  .lower-text {
    grid-column: 3 / 4;
    grid-row: 4;
    margin-top: 78px; /* Figma gap: illustration bottom -> "write & draw" */
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 20px;
    height: fit-content;
  }

  .lower-text p {
    margin: 0;
  }
}

/* Smaller mobile: tighter spacing */
@media (max-width: 480px) {
  .page-frame {
    border-width: 24px;
  }
}
