/* Light default surfaces, reversed dark Info, and original-color media. */
:root{
  --page:#F7F7F7;
  --ink:#080808;
  --identity:#080808;
  --caption:#080808;
  --panel:#EAEAEA;
  --panel-ink:#080808;
  --heading:#080808;
  --selection:#FF0338;
  --selection-ink:#080808;
}
.panel.info{
  --panel:#151515;
  --panel-ink:#EAEAEA;
  --heading:#EAEAEA;
  --selection:#FF0338;
  --selection-ink:#080808;
}

/* Tighten only the homepage identity and Info link by one percentage point. */
html body .identity,html body .identity *{letter-spacing:-0.04em!important}
html body a,html body a:hover,html body a:focus,html body a:visited{text-decoration:none!important}
/* The dialog backdrop is a separate painted surface. */
#lightbox[data-closing]::backdrop{animation:backdrop-exit 400ms ease-in-out forwards}
@keyframes backdrop-exit{to{opacity:0}}

/* Blur the site beneath projects while keeping the project itself crisp. */
.overlay{backdrop-filter:blur(0px);-webkit-backdrop-filter:blur(0px)}
.text-wake-canvas{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:15}
::highlight(wake-active){color:transparent;text-shadow:none}
@media(prefers-reduced-motion:reduce){.text-wake-canvas{display:none}::highlight(wake-active){color:inherit}}

/* Reserve the scrollbar space while modal scroll locking is active. */
html{scrollbar-gutter:stable}
.overlay{scrollbar-gutter:stable;width:var(--viewport-width,100vw)}

/* Text keeps an arrow; every actual link has a hand, including its children. */
html,html body,html body *{cursor:default}
html body a[href],html body a[href] *{cursor:pointer}

/* Underlines are reserved for project text links and Info contact links. */
a[data-underline] .link-label{
  background-image:linear-gradient(currentColor,currentColor);
  background-repeat:no-repeat;
  background-position:left bottom;
  background-size:0% 1px;
  padding-bottom:.08em;
  -webkit-box-decoration-break:clone;
  box-decoration-break:clone;
  transition:background-size 280ms cubic-bezier(.4,0,.2,1);
}
a[data-underline]:hover .link-label,a[data-underline]:focus-visible .link-label{background-size:100% 1px}
@media(prefers-reduced-motion:reduce){a[data-underline] .link-label{transition:none}}

/* One monochrome negative for both G and idle; effects never double-invert. */
html{--negative-amount:var(--idle-negative,0)}
html.is-inverted{--negative-amount:1;background:var(--page)}
html.is-inverted,html.is-inverted #lightbox,
html.is-screensaving,html.is-screensaving #lightbox{
  filter:grayscale(var(--negative-amount)) invert(var(--negative-amount));
}
html.is-inverted #lightbox::backdrop{background:var(--panel)}

/* Identity starts as symbols and resolves in place during the initial reveal. */
.js .identity{transition:none}
.intro-scramble-canvas{mix-blend-mode:difference;position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:3}
::highlight(intro-scramble){color:transparent;text-shadow:none}
@media(prefers-reduced-motion:reduce){
  .js .identity{transition:none}
  .intro-scramble-canvas{display:none}
  ::highlight(intro-scramble){color:inherit}
}

/* Invert the imagery through the fixed type, then remove color from that type only.
   The neutral pass is a sibling so it blends with the composed difference result. */
.identity{mix-blend-mode:difference;color:#f2f2f2}
.identity.identity-neutralizer{mix-blend-mode:saturation;color:#fff;z-index:3}
.identity.identity-neutralizer,.identity.identity-neutralizer *{pointer-events:none!important;user-select:none}
body:has(.intro-scramble-canvas) .identity.identity-neutralizer{visibility:hidden}


/* A terminal-style block follows Oregon without changing the Arizona lettering. */
.identity-location{white-space:nowrap}
.identity-cursor{display:inline-block;width:.44em;height:.72em;margin-left:.14em;vertical-align:-.04em;background:currentColor;animation:identity-cursor-blink 1s steps(1,end) infinite}
@keyframes identity-cursor-blink{0%,49%{opacity:1}50%,100%{opacity:0}}
body:has(.intro-scramble-canvas) .identity-cursor{visibility:hidden;animation:none}
@media(prefers-reduced-motion:reduce){.identity-cursor{animation:none}}

/* The cue enters once the identity settles, then scrambles away over the work. */
.scroll-cue,.back-to-top{color:var(--ink);opacity:.65;font-size:28px;line-height:36px}
.scroll-cue{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:4;pointer-events:none}
.scroll-cue-glyph,.back-to-top-glyph{display:block;width:36px;height:36px;text-align:center}
.back-to-top{display:inline-block}
.back-to-top-glyph{transform:rotate(180deg)}

/* Info opens and closes directly on every screen, without fade or blur. */
.panel.info{animation:none}
.overlay:has(.panel.info){backdrop-filter:none!important;-webkit-backdrop-filter:none!important}

/* Anchor both text passes to the same stable viewport, independent of scroll
   and the mobile browser's expanding/collapsing address bar. */
.identity{top:0;bottom:auto;height:100vh;height:100svh}

/* Project content appears immediately; the overlay retains its independent blur fade. */
.panel:not(.info){animation:none}

/* Info text resolves in place; the panel itself still opens instantly. */
.info-scramble-canvas{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:16}
::highlight(info-entrance){color:transparent;text-shadow:none}
