/*
 * Moonlight Web gate: login page and oauth2-proxy error page.
 * The Moonlight mark carries the page; motion grammar is "moonrise" on load
 * and a ray-by-ray spinner while Google opens.
 */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Root owns scrolling so the body can clip the oversized orbit rings. */
html {
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--color-ground);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

a {
  color: var(--color-accent-strong);
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

/* ---------- Page frame ---------- */

.gate {
  display: grid;
  grid-template-rows: auto 1fr auto;
  position: relative;
  overflow: clip;
}

.gate-top {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-5) clamp(var(--space-4), 4vw, var(--space-7)) 0;
  position: relative;
  z-index: 2;
}

.gate-main {
  --mark: min(52vh, 37vw, 520px);
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(var(--space-6), 5vw, var(--space-9));
  width: min(100%, 1360px);
  margin-inline: auto;
  padding: var(--space-5) clamp(var(--space-4), 4vw, var(--space-7));
}

.gate-foot {
  position: relative;
  z-index: 1;
  padding: var(--space-5) clamp(var(--space-4), 4vw, var(--space-7)) var(--space-5);
  color: var(--color-text-faint);
  font-size: var(--text-xs);
}

.gate-foot p {
  margin: 0;
}

.gate-foot a {
  color: var(--color-text-muted);
}

/* ---------- Language toggle ---------- */

.lang {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--seg-border);
  border-radius: var(--radius-pill);
  background: var(--seg-bg);
}

.lang-option {
  appearance: none;
  min-width: 44px;
  min-height: 32px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-text-muted);
  font: 600 var(--text-xs) / 1 var(--font-sans);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: background-color var(--duration-ui) ease, color var(--duration-ui) ease;
}

.lang-option[aria-pressed="true"] {
  background: var(--seg-active-bg);
  color: var(--seg-active-text);
}

@media (hover: hover) and (pointer: fine) {
  .lang-option[aria-pressed="false"]:hover {
    color: var(--color-text);
  }
}

/* ---------- Stage: the Moonlight mark ---------- */

.stage {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--mark);
  height: var(--mark);
  justify-self: center;
}

.orbits {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--mark) * 2.5);
  height: calc(var(--mark) * 2.5);
  transform: translate(-50%, -50%);
  pointer-events: none;
  overflow: visible;
  /* Rings bleed off the page but fade out before the text column. */
  -webkit-mask-image: linear-gradient(to right, #000 58%, transparent 70%);
  mask-image: linear-gradient(to right, #000 58%, transparent 70%);
}

.orbit {
  fill: none;
  stroke: var(--color-line-soft);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  transform-box: fill-box;
  transform-origin: center;
}

.orbit-2 {
  stroke-dasharray: 2 10;
}

.orbit-3 {
  opacity: 0.4;
}

.mark {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.mark-ring {
  fill: var(--color-brand-ring);
  transform-box: fill-box;
  transform-origin: center;
}

.mark-disc {
  fill: var(--color-brand-disc);
  transform-box: fill-box;
  transform-origin: center;
}

.mark-rays line,
.mark-rays-hot line {
  fill: none;
  stroke-width: 8;
  stroke-linecap: butt;
}

.mark-rays line {
  stroke: var(--color-brand-ring);
}

.mark-rays-hot line {
  stroke: var(--violet-600);
  opacity: 0;
}

/* ---------- Panel ---------- */

.panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 30rem;
}

.title {
  margin: 0;
  font-size: var(--text-display);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.02em;
  color: var(--color-text-strong);
  text-wrap: balance;
}

.title-web {
  font-weight: 400;
  color: var(--color-text-muted);
}

.lede {
  margin: var(--space-4) 0 0;
  max-width: 26ch;
  font-size: var(--text-lg);
  line-height: 1.4;
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* Google button: dark theme per Google Identity branding guidelines. */
.gsi {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  height: var(--gsi-height);
  margin-top: var(--space-7);
  padding: 0 22px 0 14px;
  border: 1px solid var(--gsi-border);
  border-radius: var(--radius-pill);
  background: var(--gsi-bg);
  color: var(--gsi-text);
  font: 500 16px / 1 var(--font-gsi);
  letter-spacing: 0.25px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--duration-ui) ease,
    border-color var(--duration-ui) ease,
    transform var(--duration-press) var(--ease-out);
}

.gsi-icon {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: none;
}

.gsi-icon svg {
  width: 20px;
  height: 20px;
  display: block;
}

.gsi-label {
  transition: filter var(--duration-ui) ease, opacity var(--duration-ui) ease;
}

@media (hover: hover) and (pointer: fine) {
  .gsi:hover {
    background: var(--gsi-bg-hover);
    border-color: var(--slate-200);
  }
}

.gsi:active {
  transform: scale(0.97);
}

.gsi[aria-busy="true"] {
  cursor: progress;
}

.gsi.is-swapping .gsi-label {
  filter: blur(2px);
  opacity: 0.6;
}

.note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.note-icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Signal path: PC di casa -> Raspberry Pi -> questo browser ---------- */

.signal {
  --icon: 24px;
  position: relative;
  width: 100%;
  max-width: 26rem;
  margin: var(--space-8) 0 0;
}

/* From the PC icon to the browser icon; the middle icon masks it with the ground colour. */
.signal-track {
  position: absolute;
  top: calc(var(--icon) / 2 - 1px);
  left: calc(var(--icon) + var(--space-2));
  right: calc(var(--icon) + var(--space-2));
  height: 2px;
  background: var(--signal-line);
  overflow-x: clip;
  overflow-y: visible;
}

/* Static direction marks: the flow reads left to right even when nothing moves. */
.signal-arrow {
  position: absolute;
  top: 50%;
  width: 7px;
  height: 7px;
  border-top: 1.5px solid var(--color-accent);
  border-right: 1.5px solid var(--color-accent);
  transform: translate(-50%, -50%) rotate(45deg);
}

.signal-arrow-1 {
  left: 25%;
}

.signal-arrow-2 {
  left: 75%;
}

/* Full-width carrier; its leading edge holds the pulse. Moves only with transform. */
.signal-pulse {
  position: absolute;
  inset: 0;
  transform: translateX(-56px);
}

.signal-pulse::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 56px;
  height: 2px;
  border-radius: 1px;
  background: var(--signal-pulse);
}

.signal-nodes {
  display: flex;
  justify-content: space-between;
  margin: 0;
  padding: 0;
  list-style: none;
}

.signal-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  line-height: 1.3;
  color: var(--color-text-muted);
  text-align: center;
}

.signal-node:first-child {
  align-items: flex-start;
  text-align: left;
}

.signal-node:last-child {
  align-items: flex-end;
  text-align: right;
}

.signal-icon {
  position: relative;
  z-index: 1;
  width: var(--icon);
  height: var(--icon);
  fill: none;
  stroke: var(--slate-200);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.signal-node:nth-child(2) .signal-icon {
  box-sizing: content-box;
  padding: 0 var(--space-2);
  background: var(--color-ground);
}

/* ---------- Error variant ---------- */

.gate--error .gate-main {
  --mark: min(40vh, 32vw, 400px);
}

.status-code {
  margin: var(--space-6) 0 0;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}

/* Error: the moon dims. */
.gate--error .mark-disc {
  fill: var(--slate-300);
}

.gate--error .lede {
  max-width: 40ch;
  font-size: var(--text-md);
}

.title--error {
  font-size: clamp(2.25rem, 1.4rem + 2.6vw, 3.5rem);
  line-height: 1.02;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-5);
  margin-top: var(--space-7);
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--gsi-height);
  padding: 0 var(--space-5);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-accent);
  background: var(--color-accent-deep);
  color: var(--color-text-strong);
  font: 600 var(--text-md) / 1 var(--font-sans);
  text-decoration: none;
  transition: background-color var(--duration-ui) ease, transform var(--duration-press) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .button:hover {
    background: var(--violet-600);
  }
}

.button:active {
  transform: scale(0.97);
}

.link-quiet {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* ---------- Motion: moonrise ---------- */

@media (prefers-reduced-motion: no-preference) {
  .mark-ring {
    animation: ring-rise 900ms var(--ease-moonrise) both;
  }

  .mark-disc {
    animation: disc-rise var(--duration-moonrise) var(--ease-moonrise) 120ms both;
  }

  .mark-rays line {
    stroke-dasharray: 1;
    animation: ray-draw 700ms var(--ease-out) both;
  }

  .mark-rays line:nth-child(1) { animation-delay: 420ms; }
  .mark-rays line:nth-child(2) { animation-delay: 460ms; }
  .mark-rays line:nth-child(3) { animation-delay: 500ms; }
  .mark-rays line:nth-child(4) { animation-delay: 540ms; }
  .mark-rays line:nth-child(5) { animation-delay: 580ms; }
  .mark-rays line:nth-child(6) { animation-delay: 620ms; }
  .mark-rays line:nth-child(7) { animation-delay: 660ms; }
  .mark-rays line:nth-child(8) { animation-delay: 700ms; }

  .orbit {
    animation: orbit-settle 1600ms var(--ease-moonrise) both;
  }

  .orbit-1 { animation-delay: 160ms; }
  .orbit-2 { animation-delay: 260ms; }
  .orbit-3 { animation-delay: 360ms; }

  .panel > * {
    animation: rise-in 560ms var(--ease-out) both;
  }

  .panel > :nth-child(1) { animation-delay: 240ms; }
  .panel > :nth-child(2) { animation-delay: 300ms; }
  .panel > :nth-child(3) { animation-delay: 360ms; }
  .panel > :nth-child(4) { animation-delay: 420ms; }
  .panel > :nth-child(5) { animation-delay: 480ms; }

  .gate-top,
  .gate-foot {
    animation: fade-in 600ms ease 500ms both;
  }

  /* Video travels from the home PC to this browser: one run on arrival (under 5s),
     then continuously only while connecting (state indication). */
  .signal-pulse {
    animation: signal-run 2400ms linear 1400ms 1;
  }

  /* Loading state: the logo's rays light one after another. */
  .is-connecting .mark-rays-hot line {
    animation: ray-hot 960ms linear infinite;
  }

  .is-connecting .mark-rays-hot line:nth-child(1) { animation-delay: 0ms; }
  .is-connecting .mark-rays-hot line:nth-child(2) { animation-delay: 120ms; }
  .is-connecting .mark-rays-hot line:nth-child(3) { animation-delay: 240ms; }
  .is-connecting .mark-rays-hot line:nth-child(4) { animation-delay: 360ms; }
  .is-connecting .mark-rays-hot line:nth-child(5) { animation-delay: 480ms; }
  .is-connecting .mark-rays-hot line:nth-child(6) { animation-delay: 600ms; }
  .is-connecting .mark-rays-hot line:nth-child(7) { animation-delay: 720ms; }
  .is-connecting .mark-rays-hot line:nth-child(8) { animation-delay: 840ms; }

  .is-connecting .signal-pulse {
    animation: signal-run 1200ms linear infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  .stage,
  .panel,
  .gate-top,
  .gate-foot {
    animation: fade-in 300ms ease both;
  }

  .is-connecting .mark-rays-hot line {
    opacity: 0.85;
  }
}

@keyframes ring-rise {
  from {
    opacity: 0;
    transform: scale(0.92);
  }
}

@keyframes disc-rise {
  from {
    opacity: 0;
    transform: scale(0.96);
    filter: blur(8px);
  }
}

@keyframes ray-draw {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes orbit-settle {
  from {
    opacity: 0;
    transform: scale(0.86);
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@keyframes signal-run {
  0% {
    transform: translateX(-56px);
  }
  80%,
  100% {
    transform: translateX(100%);
  }
}

@keyframes ray-hot {
  0% {
    opacity: 1;
  }
  55%,
  100% {
    opacity: 0;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  .gate-main {
    --mark: min(168px, 44vw);
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
    justify-items: center;
    gap: var(--space-6);
    padding-top: 0;
  }

  .gate--error .gate-main {
    --mark: min(128px, 36vw);
  }

  .panel {
    align-items: center;
    text-align: center;
    max-width: 26rem;
  }

  .lede {
    margin-inline: auto;
  }

  .gsi {
    width: 100%;
    max-width: 22rem;
    justify-content: center;
    margin-top: var(--space-6);
  }

  .note {
    justify-content: center;
  }

  .orbits {
    -webkit-mask-image: linear-gradient(to bottom, #000 56%, transparent 68%);
    mask-image: linear-gradient(to bottom, #000 56%, transparent 68%);
  }

  .signal {
    max-width: 22rem;
    margin-top: var(--space-7);
  }

  .actions {
    justify-content: center;
  }

  .gate-foot {
    text-align: center;
  }

  .gate-foot p {
    margin-inline: auto;
  }
}

@media (max-width: 860px) and (max-height: 640px) {
  .signal {
    display: none;
  }
}
