/* ============================================================
   Replica of raunofreiberg.com landing page — styles.
   Values extracted from the live site's CSS (light theme is
   forced on the index route, so only light tokens are used).
   ============================================================ */

:root {
  --yellow: #FFFF02;
  --orange: #FF6100;
  --colors-red: #FF484C;

  /* Radix gray (light) — only the steps the landing page uses */
  --colors-gray1: hsl(0 0% 99%);
  --colors-gray4: hsl(0 0% 93%);   /* page background (#EDEDED) */
  --colors-gray9: hsl(0 0% 56.1%);
  /* 42%, matching tokens.css: 43.5% measured 4.29:1 on the #EDEDED
     ground, a hair under small text's 4.5. (The .sheet re-pin below
     keeps 43.5 — on the sheets' white it already clears at 4.86.) */
  --colors-gray11: hsl(0 0% 42%);
  --colors-gray12: hsl(0 0% 9%);
  --colors-focus: var(--colors-gray9);

  --radii-round: 9999px;
  --root-background: var(--colors-gray4);
  --fonts-body: X, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
    "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
    "Helvetica Neue", sans-serif;

  --frame-width: 1200px;
  --frame-height: 720px;

  /* tokens the shared chrome (chrome.css) reads — the subpage values */
  --red-accent: var(--colors-red);
  --colors-gray5: hsl(0 0% 90.9%);
  --colors-gray8: hsl(0 0% 78%);
  --card-bg: #ffffff;
  --shadow-dock: 0 0 0 1px var(--colors-gray5), 0 12px 32px rgba(0, 0, 0, 0.08),
    0 2px 8px rgba(0, 0, 0, 0.04);
}

/* Dark theme (P2.3): the landing joins the theme system as a gallery
   wall — the ground drops to near-black (Radix gray dark, the same
   steps tokens.css gives the subpages) while the frame sheets stay
   lit, each artwork keeping the palette it was composed in. Only
   ground-level ink flips: labels, minimap, hints, chrome. */
html.dark {
  --colors-gray4: hsl(0 0% 8.5%);    /* page background */
  --colors-gray5: hsl(0 0% 17.9%);
  --colors-gray8: hsl(0 0% 31.2%);
  --colors-gray9: hsl(0 0% 43.9%);
  --colors-gray11: hsl(0 0% 62.8%);
  --colors-gray12: hsl(0 0% 93%);
  --card-bg: hsl(0 0% 11%);
  --shadow-dock: 0 0 0 1px var(--colors-gray5), 0 12px 32px rgba(0, 0, 0, 0.5),
    0 2px 8px rgba(0, 0, 0, 0.4);
}

/* The sheets (and the white mobile-note card) are theme-invariant:
   re-pin the gray ramp inside them to the light values, so their ink
   never follows the wall */
.sheet,
.mobile-note {
  --colors-gray8: hsl(0 0% 78%);
  --colors-gray9: hsl(0 0% 56.1%);
  --colors-gray11: hsl(0 0% 43.5%);
  --colors-gray12: hsl(0 0% 9%);
}

@supports (color: color(display-p3 1 1 1)) {
  :root {
    --orange: color(display-p3 0.99 0.4 0.02);
  }
}

/* The site serves PP Neue Montreal Medium as family "X" for both weights */
@font-face {
  font-family: X;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/dd.woff2) format("woff2");
}
@font-face {
  font-family: X;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/dd.woff2) format("woff2");
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html,
body {
  background: var(--root-background);
}

html {
  overscroll-behavior: none;
  touch-action: pan-x pan-y;
  scrollbar-width: none;
}
html::-webkit-scrollbar {
  display: none;
}

body {
  margin: 0;
  font-family: var(--fonts-body);
}

::selection {
  background: var(--yellow);
  color: black;
}

h1, h2, h3, h4, h5, h6, p { margin: 0; }
h1, h2, h3 { font-weight: 500; }

/* the original site sets its italic voice in Georgia */
em, i { font-family: Georgia, serif; }

a {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

button {
  padding: 0;
  margin: 0;
  background: transparent;
  font-family: var(--fonts-body);
  border: 0;
}

/* visually hidden (aria-live region) */
.vh {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  overflow: hidden;
  white-space: nowrap;
  position: absolute;
}

/* ---------------- layout ---------------- */

.ghost {
  pointer-events: none;
  user-select: none;
}

.center,
.cross {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.cross {
  mix-blend-mode: difference;
  cursor: pointer;
}

.frames {
  display: flex;
  gap: 8px;
  flex-direction: row;
  width: var(--frame-width);
  height: var(--frame-height);
  will-change: transform;
}

@keyframes fadeFrames {
  to { opacity: 1; }
}

.frame {
  outline: 0;
  user-select: none;
  -webkit-user-select: none;
}
.frame:not([data-variant="main"]) {
  opacity: 0;
  animation: fadeFrames 0.35s ease-in-out 0.8s forwards;
}
.root[data-cancel-animation="true"] .frame {
  animation-delay: 0s;
}
.frame:focus-visible [data-sheet] {
  outline: 4px solid var(--colors-focus);
  outline-offset: 4px;
}

.frame a,
.frame h1 span,
.frame p {
  font-size: 85px;
  font-weight: 400;
}
.frame p[data-size="medium"] {
  font-size: 75px;
}
/* The Projects frame's label is a real (non-decorative) heading, so it
   is an h2 — the outline must not jump h1 to h3 — in the same elephant
   type. Scoped to .contents: the Player One sheet also carries an h2
   (.p1-name, 140px) and a bare `.frame h2` out-specified it to 720px,
   bursting that sheet. */
.frame .contents h2,
.frame h3 {
  font-size: 720px;
  font-weight: 400;
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}

.sheet {
  width: 100%;
  height: 100%;
  background: white;
  overflow-x: clip;
}
.sheet-yellow {
  background: var(--yellow);
}

.contents {
  display: flex;
  align-items: center;
  height: 100%;
}
.contents[data-color="yellow"] {
  background: var(--yellow);
  padding: 50px;
}
/* mantra sheet: cited question (serif italic, top left) answered in the
   site's own voice (grotesk, bottom right) — a diagonal call-and-response */
.contents[data-color="yellow"] {
  position: relative;
}
.frame p.mantra-question {
  position: absolute;
  top: 50px;
  left: 50px;
  line-height: 1.15;
}
.frame p.mantra-answer {
  position: absolute;
  right: 50px;
  bottom: 50px;
  text-align: right;
  line-height: 1.15;
}
.frame p.mantra-source {
  position: absolute;
  left: 50px;
  bottom: 68px;
  font-size: 14px;
  color: var(--colors-gray11);
}

.centerFull {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.centerFull > svg {
  flex-shrink: 0;
}
.centerFull > svg[data-icon="history"] {
  height: 50%;
  width: fit-content;
}
.scaleUp svg {
  scale: 1.2;
}

/* main intro sheet */
.main {
  padding: 64px;
  display: flex;
  align-items: center;
  gap: 64px;
  color: var(--colors-gray12);
}

.circle {
  border-radius: var(--radii-round);
  aspect-ratio: 1 / 1;
}
.circle-main {
  background: var(--yellow);
  height: 100%;
  position: absolute;
  display: flex;
  right: 0;
  top: 0;
}
.circle-dd {
  background: var(--orange);
  height: 100%;
}

.label {
  font-size: 14px;
  color: var(--colors-gray11);
  position: absolute;
  transform-origin: top left;
  top: -28px;
}

/* six-row hero block (rauno.me's alternating-indent sheet) at the
   frame's own 85px: six rows at 1.15 land 586.5px in the sheet's
   592px inner height, and the longest drum row ("recursive
   self-improvement", 1003px wide) ends at x=1131 of the 1200 sheet —
   measured, no clipping */
.frame h1 {
  line-height: 1.15;
}

.clipReveal {
  display: block;
  overflow: hidden;
}
/* the entrance grips ONLY the static reveal span — a bare
   ".clipReveal span" would also grip the promoted drum's chars,
   ghosts, measurer and escort with an entrance translateY and an
   inline-block that belong to the reveal alone (round 11 scoping) */
.clipReveal > [data-reveal] {
  display: inline-block;
  transform: translateY(100px);
}
.clipReveal[data-variant="offset"] {
  margin-left: 64px;
}

/* ---- the rotating role line (hero.js, staggered-text engine) ----
   chars are absolutely placed around a zero-width line so a glyph
   swapping mid-flight never reflows the settled ones; each glyph
   carries its own perspective() inside its transform, so it turns
   about itself, upright — no shared vanishing point to shear it */
.hero-role-line {
  display: block;
  position: relative;
  height: 1.15em;
  line-height: 1.15;
}
.hero-role-line[data-variant="offset"] {
  margin-left: 64px; /* the clipReveal offset rhythm, carried down */
}
.st-line {
  position: relative;
  display: block;
  width: 0;
  height: 1.15em;
}
.st-char {
  position: absolute;
  top: 0;
  left: 0;
  line-height: 1.15;
  white-space: pre;
  will-change: transform, opacity, filter;
  transform-origin: 50% 50%; /* the roll turns about the glyph's middle */
  backface-visibility: hidden;
}
.st-measure {
  position: absolute;
  left: 0;
  top: 0;
  width: auto;
  height: auto;
  display: inline-flex;
  visibility: hidden;
  pointer-events: none;
}
.st-measure .st-char { position: static; }

/* ---- round 10: identity rows promoted to drums, lazily, at their
   first wildcard. Promotion releases the entrance clip, keeps the
   static for the line box (and the vertical truth of the saltires),
   and floats the drum over the same origin. */
.clipReveal[data-drummed] {
  position: relative;
  overflow: visible;
}
.clipReveal[data-drummed] > [data-reveal] {
  visibility: hidden;
}
.clipReveal .st-line {
  position: absolute;
  left: 0;
  top: 0;
  transform: none; /* escapes the entrance's translateY(100px) */
}
/* the city marks' escorts: each mark leaves and returns with its
   word, wearing the drum's own pose (transform/blur/opacity set
   inline). Doubled class: it must out-rank the marks' own margins
   below. */
.ams-escort.ams-xxx,
.ams-escort.bkk-buddha {
  position: absolute;
  margin-left: 0;
  will-change: transform, opacity, filter;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
}
/* the city link, promoted: a quiet hitbox over the drum's word,
   retargeted city to city (Amsterdam at home, Bangkok abroad) */
.ams-hit {
  position: absolute;
  z-index: 2;
}
.ams-hit:focus-visible {
  outline: 2px solid var(--colors-focus);
  outline-offset: 4px;
  border-radius: 6px;
}

/* row two's Ams — the city abstracted to its own mark: the three
   St Andrew's saltires stacked vertically beside the word, as they
   stand on Amsterdam's coat of arms. Proportions measured from
   Tony's reference (cross 56, gap 12, stroke 16.3 — 29% weight,
   21% gaps), scaled so the ink spans exactly cap height: top tips
   at the capitals, bottom tips on the baseline (endpoints inset
   0.354×stroke so the butt caps don't overshoot the box). It rides
   inside the link in currentColor — the word's own ink, through
   themes and the blueprint alike. */
.ams-xxx {
  width: 17.8px;
  height: 61px;
  margin-left: 14px;
}
.ams-xxx path {
  fill: none;
  stroke: currentColor;
  stroke-width: 5.2;
}
/* row two abroad — BKK's mark: the seated Buddha of Tony's reference
   abstracted to a single closed outline (needle finial, stepped
   crown, the neck's dip, folded legs on their cushion), drawn clean
   from the silhouette's measured proportions (0.7735 aspect) and
   standing the saltires' own cap height, a solid in the word's ink.
   The template hides in the markup; the drum clones it for escort
   duty at promotion. */
.bkk-buddha {
  width: 47.2px;
  height: 61px;
  margin-left: 14px;
}
/* the hidden attribute is HTML's — an svg element never hears the
   UA's [hidden]{display:none}, so the template must be told in CSS
   or it renders inline beside the static from the first paint */
.bkk-buddha[hidden] {
  display: none;
}
.bkk-buddha path {
  fill: currentColor;
  stroke: none;
}
/* the reveal's overflow:hidden clips an outer ring into two floating
   bars — draw the site's ring INSIDE the link's own box instead */
.frame h1 a:focus-visible {
  outline: 2px solid var(--colors-focus);
  outline-offset: -2px;
}

h1 {
  position: relative;
}

/* contact frame */
.contact {
  --padding: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: relative;
}
.contact button {
  cursor: copy;
}
.contact a,
.contact button {
  color: var(--colors-gray12);
  border-radius: 12px;
}
.contact a:focus-visible,
.contact button:focus-visible {
  outline: 4px solid var(--colors-focus);
  outline-offset: 4px;
}
.contact a[data-position="top-left"] { position: absolute; top: var(--padding); left: var(--padding); }
.contact a[data-position="top-right"] { position: absolute; top: var(--padding); right: var(--padding); }
.contact a[data-position="bottom-left"] { position: absolute; bottom: var(--padding); left: var(--padding); }
.contact a[data-position="bottom-right"] { position: absolute; bottom: var(--padding); right: var(--padding); }

.email {
  display: grid;
  place-items: center;
  overflow: hidden;
}
.email > * {
  grid-area: 1 / 1;
}
.email p {
  font-size: 85px;
  font-weight: 400;
}

/* ---------------- minimap ---------------- */

.minimap {
  position: fixed;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  --line-width: 1px;
  --line-height: 18px;
  --line-gap: 9px;
  --line-color: var(--colors-gray9);
  --tracker-width: 30px;
}
.minimap-inner {
  display: flex;
  align-items: flex-end;
  gap: var(--line-gap);
}
.minimap .line {
  width: var(--line-width);
  height: var(--line-height);
  background: var(--line-color);
  position: relative;
}
.minimap .tracker {
  width: var(--tracker-width);
  height: var(--line-height);
  position: absolute;
  background: transparent;
  border: var(--line-width) solid var(--line-color);
}

/* ---------------- debug (wireframe) mode: click the cross ----------------
   the wire takes the theme's ink: black lines on the light ground,
   white on the dark one — a blueprint either way, never ink-on-ink */

.root[data-debug="true"] {
  --wire: #000;
}
.dark .root[data-debug="true"] {
  --wire: #fff;
}
.root[data-debug="true"] .circle,
.root[data-debug="true"] .contents,
.root[data-debug="true"] .main {
  background: transparent;
}
.root[data-debug="true"] .circle {
  border: 1px solid var(--wire);
}
.root[data-debug="true"] [data-sheet] {
  border: 1px solid var(--wire);
  background: transparent;
}
.root[data-debug="true"] [data-sheet] svg path {
  stroke: var(--wire);
  stroke-width: 1px;
}
.root[data-debug="true"] .contact a,
.root[data-debug="true"] h1 span,
.root[data-debug="true"] h2,
.root[data-debug="true"] h3,
.root[data-debug="true"] p {
  color: transparent;
  -webkit-text-stroke: 1px var(--wire);
}
/* small type can't live as a 1px hairline — the hover captions take
   the wire as fill instead */
.root[data-debug="true"] .p1-key-cap i {
  color: var(--wire);
}
.root[data-debug="true"] [data-icon="history"] path {
  stroke: var(--wire);
  fill: var(--wire);
  stroke-width: 0px;
}
.root[data-debug="true"] .frame h1 a {
  color: transparent;
  -webkit-text-stroke: 1px var(--wire);
}
/* the crosses join the blueprint as hairlines */
.root[data-debug="true"] .ams-xxx path {
  stroke: var(--wire);
  stroke-width: 1px;
}
.root[data-debug="true"] .bkk-buddha path {
  fill: none;
  stroke: var(--wire);
  stroke-width: 1px;
}

/* ---------------- touch devices: native horizontal scroll ---------------- */

@media (pointer: coarse) {
  .ghost {
    height: 1px !important;
  }
  .center {
    position: absolute;
    display: flex;
    align-items: center;
    height: 100%;
    transform: none;
    top: 0;
    left: 0;
  }
  .mainContainer {
    position: absolute;
  }
}

/* ---------------- player one: the frame before the beginning ---------------- */

.playerOne {
  visibility: hidden;
}
.playerOne[data-revealed="true"] {
  visibility: visible;
}
.p1-sheet {
  position: relative;
  color: var(--colors-gray12);
  transform: scale(0.94);
  opacity: 0;
  transition: transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.4s ease;
}
.playerOne[data-revealed="true"] .p1-sheet {
  transform: scale(1);
  opacity: 1;
}

/* the frame speaks the site's diagonal grammar: identity top-left,
   links bottom-right, the copper key bottom-left as the signature */
.p1-top {
  position: absolute;
  top: 52px;
  left: 64px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.frame .p1-kicker {
  font-size: 22px;
  color: var(--colors-gray11);
}
.p1-kicker i {
  font-family: Georgia, serif;
}
.p1-name {
  font-size: 140px;
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: -0.01em;
}
.frame .p1-text {
  font-size: 21px;
  line-height: 1.5;
  color: var(--colors-gray12);
}
.p1-links {
  position: absolute;
  right: 64px;
  bottom: 52px;
  display: flex;
  gap: 26px;
}
.frame .p1-links a {
  font-size: 18px;
  color: var(--colors-gray12);
}
.frame .p1-links a:hover,
.frame .p1-links a:focus-visible {
  background: var(--yellow);
  outline: 0;
}
/* the three keys spin in the empty band beside the kicker;
   the hovered one whispers its line in a reserved strip below them */
.p1-keys-wrap {
  position: absolute;
  left: 480px;
  top: 24px;
  width: 640px;
  height: 260px;
  pointer-events: none;
}
.p1-keys-wrap canvas {
  position: absolute;
  top: 0;
  left: 0;
}
.frame .p1-key-cap {
  position: absolute;
  top: 224px;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 14px;
  color: var(--colors-gray12);
  opacity: 0;
  transition: opacity 0.45s ease;
}
.p1-key-cap i {
  font-family: Georgia, serif;
}
.p1-key-cap[data-cap="0"] { left: 100px; }
.p1-key-cap[data-cap="1"] { left: 300px; }
.p1-key-cap[data-cap="2"] { left: 500px; }
.p1-key-cap[data-show="true"] { opacity: 1; }

/* the four anchors arrive in reading order: identity, spectrum, links, keys */
.p1-top,
.p1-spectrum,
.p1-links,
.p1-keys-wrap {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.playerOne[data-revealed="true"] .p1-top { transition-delay: 0.08s; }
.playerOne[data-revealed="true"] .p1-spectrum { transition-delay: 0.2s; }
.playerOne[data-revealed="true"] .p1-links { transition-delay: 0.32s; }
.playerOne[data-revealed="true"] .p1-keys-wrap { transition-delay: 0.4s; }
.playerOne[data-revealed="true"] .p1-top,
.playerOne[data-revealed="true"] .p1-spectrum,
.playerOne[data-revealed="true"] .p1-links,
.playerOne[data-revealed="true"] .p1-keys-wrap {
  opacity: 1;
  transform: none;
}

/* the spectrum: one frame-wide gesture. eight fields, each a frequency;
   under the cursor the band magnifies and turns copper (the key's metal) */
.p1-spectrum {
  position: absolute;
  left: 64px;
  right: 64px;
  top: 322px;
}
.p1-spec-labels {
  position: relative;
  height: 38px;
}
.p1-spec-labels[data-side="top"] {
  margin-bottom: 16px;
}
.p1-spec-labels[data-side="bottom"] {
  margin-top: 16px;
}
.frame .p1-spec-labels span {
  position: absolute;
  transform: translateX(-50%);
  font-size: 14px;
  line-height: 1.35;
  text-align: center;
  color: var(--colors-gray12);
  transition: background-color 0.15s ease;
  white-space: nowrap;
}
.p1-spec-labels[data-side="top"] span {
  bottom: 0;
}
.p1-spec-labels span[data-zone="0"] { left: 6.25%; }
.p1-spec-labels span[data-zone="1"] { left: 18.75%; }
.p1-spec-labels span[data-zone="2"] { left: 31.25%; }
.p1-spec-labels span[data-zone="3"] { left: 43.75%; }
.p1-spec-labels span[data-zone="4"] { left: 56.25%; }
.p1-spec-labels span[data-zone="5"] { left: 68.75%; }
.p1-spec-labels span[data-zone="6"] { left: 81.25%; }
.p1-spec-labels span[data-zone="7"] { left: 93.75%; }
.p1-spec-labels span[data-pole="true"] {
  font-weight: 500;
}
.p1-spec-labels span[data-active="true"] {
  background: var(--yellow);
}
.p1-spec-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 96px;
  cursor: crosshair;
  touch-action: none;
}
.p1-spec-band .bar {
  width: 2px;
  background: var(--colors-gray9);
  transition: transform 0.14s ease-out, background-color 0.14s ease-out;
  will-change: transform;
}
.frame .p1-status {
  margin-top: 18px;
  min-height: 22px;
  text-align: center;
  font-size: 14px;
}
.p1-status i {
  font-family: Georgia, serif;
  color: var(--colors-gray11);
}
.p1-status i[data-hidden="true"] {
  display: none;
}
.frame .p1-status span {
  font-family: Menlo, Consolas, monospace;
  font-size: 14px;
  color: var(--colors-gray11);
}

/* ---------------- wittgenstein, silkscreened on the mantra sheet ---------------- */

.mantra-witt {
  position: absolute;
  top: 12px;
  right: 96px;
  height: calc(100% - 24px);
  pointer-events: none;
  z-index: 0;
}
.frame p.mantra-question,
.frame p.mantra-answer,
.frame p.mantra-source {
  z-index: 1;
}

/* the hint chip, left of the minimap */
.p1-hint {
  position: fixed;
  top: 58px;
  right: calc(50% + 128px);
  z-index: 20;
  border: 0;
  background: transparent;
  padding: 6px 10px;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  /* visibility keeps the hidden button out of the tab order for its
     first seconds; its delay holds the fade smooth on the way out */
  visibility: hidden;
  transition: opacity 0.8s ease, transform 0.8s ease, visibility 0s 0.8s;
}
.p1-hint[data-show="true"] {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  visibility: visible;
  transition-delay: 0s;
}
.p1-hint i {
  font-family: Georgia, serif;
  font-style: italic;
  font-size: 14px;
  color: var(--colors-gray11);
  white-space: nowrap;
  transition: color 0.2s ease;
}
.p1-hint:hover i {
  color: var(--colors-gray12);
}
.p1-hint:focus-visible {
  outline: 2px solid var(--colors-focus);
  border-radius: 6px;
}

/* ---- scroll hint: the riddle's practical twin, right of the minimap ----
   A miniature ruler; the yellow tracker (the site's "you are here" mark)
   fades in at the start, holds, glides right, dissolves. */
.scroll-hint {
  position: fixed;
  top: 58px;
  left: calc(50% + 128px);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.scroll-hint[data-show="true"] {
  opacity: 1;
  transform: none;
}
.scroll-hint i {
  font-family: Georgia, serif;
  font-style: italic;
  font-size: 14px;
  color: var(--colors-gray11);
  white-space: nowrap;
}
.scroll-hint-demo {
  position: relative;
  width: 41px;
  height: 12px;
}
.scroll-hint-demo .sh-line {
  position: absolute;
  top: 0;
  width: 1px;
  height: 12px;
  background: var(--colors-gray8);
}
.scroll-hint-demo .sh-line:nth-child(1) { left: 0; }
.scroll-hint-demo .sh-line:nth-child(2) { left: 10px; }
.scroll-hint-demo .sh-line:nth-child(3) { left: 20px; }
.scroll-hint-demo .sh-line:nth-child(4) { left: 30px; }
.scroll-hint-demo .sh-line:nth-child(5) { left: 40px; }
.scroll-hint-demo .sh-tracker {
  position: absolute;
  top: 0;
  left: 0;
  width: 16px;
  height: 12px;
  background: var(--yellow);
  opacity: 0;
  animation: shTravel 2.8s cubic-bezier(0.45, 0.05, 0.25, 1) infinite;
}
@keyframes shTravel {
  0%   { transform: translateX(0);    opacity: 0; }
  12%  { transform: translateX(0);    opacity: 1; }
  30%  { transform: translateX(0);    opacity: 1; }
  74%  { transform: translateX(25px); opacity: 1; }
  90%  { transform: translateX(25px); opacity: 0; }
  100% { transform: translateX(25px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-hint {
    transition: opacity 0.8s ease;
    transform: none;
  }
  .scroll-hint-demo .sh-tracker {
    animation: none;
    transform: translateX(12px);
    opacity: 1;
  }
}
@media (max-width: 640px) {
  .scroll-hint {
    display: none;
  }
}

/* ---- colophon: the debt at the foot of the menu ----
   whisper-set like the riddle and the ruler, one size softer; the
   line ignores the cursor — only the name itself answers it */
.colophon {
  position: fixed;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  pointer-events: none;
}
.colophon i {
  font-family: Georgia, serif;
  font-style: italic;
  font-size: 11.5px;
  color: var(--colors-gray9);
  white-space: nowrap;
}
.colophon a {
  color: var(--colors-gray11);
  text-decoration: none;
  border-bottom: 1px solid var(--colors-gray8);
  pointer-events: auto;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.colophon a:hover {
  color: var(--colors-gray12);
  border-color: var(--colors-gray9);
}
.colophon a:focus-visible {
  outline: 2px solid var(--colors-focus);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  .p1-sheet,
  .p1-top,
  .p1-spectrum,
  .p1-links,
  .p1-keys-wrap,
  .p1-hint {
    transition: none;
  }
}

/* ---------------- a confession card for touch-first visitors ---------------- */

.mobile-note {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 40;
  max-width: 430px;
  margin: 0 auto;
  background: white;
  color: var(--colors-gray12);
  padding: 24px 24px 22px;
  overflow: hidden;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.18);
  transform: translateY(calc(100% + 24px));
  transition: transform 0.65s cubic-bezier(0.2, 0.9, 0.3, 1.08);
}
.mobile-note[data-show="true"] {
  transform: none;
}
.mobile-note-circle {
  position: absolute;
  top: -72px;
  right: -72px;
  width: 152px;
  height: 152px;
  border-radius: var(--radii-round);
  background: var(--yellow);
}
.mobile-note-mac {
  position: absolute;
  top: 18px;
  right: 16px;
}
.mobile-note-kicker {
  font-size: 14px;
  color: var(--colors-gray11);
  margin-bottom: 10px;
}
.mobile-note-line {
  font-size: 21px;
  font-weight: 500;
  line-height: 1.25;
  max-width: 250px;
}
.mobile-note-sub {
  font-size: 14px;
  color: var(--colors-gray11);
  margin-top: 10px;
  max-width: 270px;
  line-height: 1.45;
}
.mobile-note-btn {
  margin-top: 18px;
  font-size: 15px;
  font-weight: 500;
  padding: 10px 18px;
  background: var(--colors-gray12);
  color: white;
  cursor: pointer;
}
.mobile-note-btn:active {
  background: black;
}
@media (prefers-reduced-motion: reduce) {
  .mobile-note {
    transform: none;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  .mobile-note[data-show="true"] {
    opacity: 1;
  }
}
