/* The Digital ⇄ Photo switch, shared by both worlds, and the shutter that
   carries you between them. Each page defines --bg, --fg, --dim and --accent;
   the switch also needs each world's accent by name, because the side you're
   not on is lit in the colour of the world it leads to. */
:root{--world-digital:oklch(0.84 0.14 186);--world-photo:oklch(0.84 0.14 82)}

/* A fixed box, the same in both worlds: each page may set its labels in its
   own typeface (the Photo page does), and the switch must not change size or
   move when it does — only the lettering changes, like the wordmark. */
[data-world-switch]{
  position:relative;display:inline-grid;grid-template-columns:1fr 1fr;flex:none;box-sizing:border-box;
  width:200px;height:37px;padding:3px;border:1px solid color-mix(in oklab,var(--fg) 32%,transparent);border-radius:999px;
  background:color-mix(in oklab,var(--bg) 72%,transparent);
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:11px;line-height:1;
  letter-spacing:.16em;text-transform:uppercase;white-space:nowrap;
}
[data-world-switch] > [data-knob]{
  position:absolute;top:3px;bottom:3px;left:3px;width:calc(50% - 3px);border-radius:999px;
  background:var(--accent);box-shadow:0 0 18px color-mix(in oklab,var(--accent) 55%,transparent);
  transition:transform .5s cubic-bezier(.7,0,.2,1),background-color .45s ease,box-shadow .45s ease;
}
[data-world-switch][data-world="photo"] > [data-knob]{transform:translateX(100%)}
/* Leaning towards the other world on hover says the knob can be pushed. */
[data-world-switch][data-world="digital"]:has(> a[data-world-go="photo"]:hover) > [data-knob]{transform:translateX(12%)}
[data-world-switch][data-world="photo"]:has(> a[data-world-go="digital"]:hover) > [data-knob]{transform:translateX(88%)}
[data-world-switch] > a{
  position:relative;z-index:1;display:grid;place-items:center;padding:0 10px;text-align:center;
  text-decoration:none;border-radius:999px;transition:color .35s ease,text-shadow .35s ease;
}
[data-world-switch] > a[data-world-go="digital"]{color:var(--world-digital)}
[data-world-switch] > a[data-world-go="photo"]{color:var(--world-photo)}
[data-world-switch] > a:not([aria-current]):hover{text-shadow:0 0 12px currentColor}
[data-world-switch] > a[aria-current="page"]{color:var(--bg)}

/* Once per visit the knob nudges towards the other world, so the switch
   reads as a control and not as a label. */
[data-world-switch].is-peeking[data-world="digital"] > [data-knob]{animation:world-peek-r 1.1s cubic-bezier(.5,0,.3,1) 2}
[data-world-switch].is-peeking[data-world="photo"] > [data-knob]{animation:world-peek-l 1.1s cubic-bezier(.5,0,.3,1) 2}
[data-world-switch].is-peeking > a:not([aria-current]){animation:world-peek-glow 1.1s ease 2}
@keyframes world-peek-r{0%,100%{transform:translateX(0)}45%{transform:translateX(20%)}}
@keyframes world-peek-l{0%,100%{transform:translateX(100%)}45%{transform:translateX(80%)}}
@keyframes world-peek-glow{45%{text-shadow:0 0 14px currentColor}}

/* Set on <html> by world-switch.js the moment the other world is clicked:
   the knob slides across, taking on the destination's colour. */
html[data-world-leaving="photo"] [data-world-switch] > [data-knob]{transform:translateX(100%);background-color:var(--world-photo);box-shadow:0 0 22px color-mix(in oklab,var(--world-photo) 60%,transparent)}
html[data-world-leaving="digital"] [data-world-switch] > [data-knob]{transform:translateX(0);background-color:var(--world-digital);box-shadow:0 0 22px color-mix(in oklab,var(--world-digital) 60%,transparent)}
html[data-world-leaving] [data-world-switch] > a[aria-current="page"]{color:var(--dim)}
html[data-world-leaving] [data-world-switch] > a:not([aria-current]){color:var(--bg)}

/* The shutter: two blades, drawn on <html> itself so they sit outside
   anything the page renders, close from the edges with a line of the
   destination's light on their leading edge. The next page starts with them
   shut (the inline script in its <head>) and opens them once it has
   something to show. */
html::before,html::after{
  content:"";position:fixed;left:0;right:0;height:50.5vh;z-index:2147483000;pointer-events:none;
  background:var(--shutter,#06070a);transform:scaleY(0);
}
html::before{top:0;transform-origin:50% 0;box-shadow:0 2px 0 var(--seam,transparent)}
html::after{bottom:0;transform-origin:50% 100%;box-shadow:0 -2px 0 var(--seam,transparent)}
html[data-world-leaving]::before,html[data-world-leaving]::after{transform:scaleY(1);transition:transform .45s cubic-bezier(.7,0,.3,1)}
/* The failsafe animation opens the blades by itself after three seconds, so
   a page whose script never loads can't stay shut. */
html.world-arriving::before,html.world-arriving::after{transform:scaleY(1);animation:world-failsafe 0s linear 3s forwards}
html.world-opening::before,html.world-opening::after{transform:scaleY(0);transition:transform .7s cubic-bezier(.2,.8,.2,1)}
@keyframes world-failsafe{to{transform:scaleY(0)}}

@media (max-width:400px){
  [data-world-switch]{width:172px;height:35px}
  [data-world-switch] > a{padding:0 8px;letter-spacing:.12em}
}
@media (prefers-reduced-motion:reduce){
  [data-world-switch] > [data-knob],[data-world-switch] > a{transition:none;animation:none}
}
