/* Drzwi Pitwalla (docs/projekt-v1.md §21.6.2–§21.6.3): okładka z rozmytego podglądu, rysowany panel ze szkła, w nim
   rysowane przyciski, a po kliknięciu szklany dialog. Ruch to tylko opacity i transform. Szkło (backdrop-filter) nie
   ma przodka z opacity < 1, backdrop-filter, filter, mask ani clip-path, bo taki przodek odciąłby mu tło okładki;
   dlatego panel i przyciski leżą w drzewie obok siebie, a dialog w warstwie górnej. */
@font-face { font-family: "Plex"; font-weight: 600; font-display: swap; src: url("/fonts/IBMPlexSans-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "Plex"; font-weight: 400; font-display: swap; src: url("/fonts/IBMPlexSans-Regular.woff2") format("woff2"); }

:root {
  --bg: #7a8681;   /* średni kolor okładki: tło przed pierwszym obrazem */
  --ink: #fff;
  --glass-tint: rgba(6, 34, 42, 0.6);
  --line: rgba(255, 255, 255, 0.24);
  --well: rgba(0, 0, 0, 0.28);
  --r-ctl: 4px;    /* zaokrąglenia kokpitu (css/tokens.css): przyciski i pola */
  --r-pop: 8px;    /* panel i dialog */
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  --draw: cubic-bezier(0.6, 0.1, 0.3, 1);
  --mono: 500 14px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font: 600 17px/1.2 Plex, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.stage { position: fixed; inset: 0; overflow: hidden; }
.lqip, .cover, .cover img, .veil { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Podgląd 32×18 (img/okladka-podglad.webp, przepis w img/ZRODLA) od pierwszego malowania. */
.lqip {
  background: url("data:image/webp;base64,UklGRlgBAABXRUJQVlA4IEwBAACQBwCdASogABIAPtFUokuoJKMhsAgBABoJZACdMoMtNRV5/8S3ZoGWDwA0rjNIxh9absh7ygcoEpC03TXQ5d96yuUwjAAA/qqY1p0fTgtqiaXQZSNwwiD1G0JWKg62xIhxOhFnuhhQkylnn7qgek8kftd9VFE5RmhXypE76RXxJXjszOAx2wVDxBY0NFvABlknD0e0q+Ld2ZMq6Jv/88dMkPOfLyOhg75amkWJPiexa2RhYPs7p0dyGgmDLE01M95s3JddnUOGpDXjalKxcI10UpYs+8rGtgU4F/DCQ2GGkbE9mwK8/IBOKv0xUd0msghR6WOFCCOeCPnOv+e8/8ihZ4lrFqDcDU9xIB4RUi9HgO00Iqc+zbrt/XWQPpEGXKxs9nUq1/DO3GKbAr+u2wc5E50vFfWMFLxeHXQ05Vi1npJzDn8rlgybjdEAAA==") 48% 50% / cover no-repeat;
  filter: blur(22px) saturate(1.1);
  transform: scale(1.12);
}

/* Przenikanie z podglądu (900 ms) ze zbliżeniem, które osiada w 1,4 s; potem dryf 36 s. */
.cover { display: block; opacity: 0; transform: scale(1.04); transition: opacity 900ms var(--ease-out), transform 1400ms var(--ease-out); }
.cover img { object-fit: cover; object-position: 48% 50%; }
.ready .cover { opacity: 1; transform: none; }
.drift .cover img { animation: drift 36s ease-in-out infinite alternate; }
@keyframes drift { to { transform: scale(1.05) translate3d(-1.2%, -0.8%, 0); } }

/* Winieta pod panelem. */
.veil {
  background: radial-gradient(ellipse 70% 60% at 50% 56%, rgba(6, 16, 18, 0.32) 0%, rgba(6, 16, 18, 0.12) 55%, rgba(6, 16, 18, 0.4) 100%);
  opacity: 0;
  transition: opacity 1200ms ease;
}
.ready .veil { opacity: 1; }

/* Panel pod przyciskami: lekkie szkło z obwódką rysowaną od środka górnej krawędzi w obie strony. */
.panel, .actions { position: absolute; left: 50%; top: 56%; transform: translate(-50%, -50%); }
.panel {
  width: min(480px, calc(100vw - 32px));
  height: 240px;
  border-radius: var(--r-pop);
  transform: translate(-50%, -50%) scale(0.96);
  transition: transform 700ms var(--ease-out);
}
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.02) 60%), rgba(8, 26, 32, 0.24);
  -webkit-backdrop-filter: blur(7px) saturate(1.3);
  backdrop-filter: blur(7px) saturate(1.3);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.24), inset 0 0 20px rgba(255, 255, 255, 0.05);
  opacity: 0;
  transition: opacity 520ms ease 200ms;
}
.framed .panel { transform: translate(-50%, -50%); }
.framed .panel::before { opacity: 1; }

/* Obwódka szkła (panel, przyciski, dialog): dwie połówki od środka górnej krawędzi do środka dolnej, liczone przez
   door.js w pikselach elementu. Biała kreska z maską jasności jak w szkle Apple: najjaśniejsza góra z blikiem w lewym
   górnym rogu, boki przygaszone, dół jaśniejszy od boków z blikiem w prawym dolnym rogu. */
.rim {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  --rim: linear-gradient(to bottom right, rgb(0 0 0 / 0.75), transparent 25%, transparent 75%, rgb(0 0 0 / 0.4)),
         linear-gradient(rgb(0 0 0 / 0.7), rgb(0 0 0 / 0.14) 25%, rgb(0 0 0 / 0.12) 75%, rgb(0 0 0 / 0.3));
  -webkit-mask-image: var(--rim);
  mask-image: var(--rim);
  transition: opacity 300ms ease;
}
.rim path {
  fill: none;
  stroke: #fff;
  stroke-width: 1.5;
  stroke-dasharray: 101;   /* odrobinę dłużej niż ścieżka (pathLength 100): bez szczeliny między połówkami */
  stroke-dashoffset: 101;
}
.framed .panel .rim path { animation: stroke 640ms var(--draw) forwards; }
@keyframes stroke { to { stroke-dashoffset: 0; } }

.actions { display: flex; flex-direction: column; gap: 14px; }

/* Przyciski równej wielkości: ikona przy lewej krawędzi, napis na środku. */
.cta {
  position: relative;
  display: block;
  width: min(304px, calc(100vw - 72px));
  height: 52px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-ctl);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  letter-spacing: 0.01em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cta:focus { outline: none; }
.cta:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }
.face {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0 48px;
  overflow: hidden;
  border-radius: inherit;
}
/* Połysk: jasny pas raz przechodzi po przycisku, gdy ten już stoi. */
.face::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 45%;
  background: linear-gradient(105deg, transparent 20%, rgba(255, 255, 255, 0.22) 50%, transparent 80%);
  transform: translateX(-100%);
}
.shown .login .face::after { animation: sheen 1000ms ease-in-out 1000ms both; }
.shown .join .face::after { animation: sheen 1000ms ease-in-out 1250ms both; }
@keyframes sheen { to { transform: translateX(225%); } }
.label { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); }
/* Poniżej 360 px napis na środku miejsca obok ikony, żeby „Dołącz maszynę do floty” się nie łamał. */
@media (max-width: 359px) { .face { padding: 0 10px 0 46px; } }
.ico {
  position: absolute;
  left: 16px;
  top: 15px;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));
  transition: transform 260ms var(--ease-out);
}
.ico .fill { fill: currentColor; stroke: none; }
.login .ico { transform-origin: 21% 90%; }   /* u dołu drzewca */

/* Szkło przycisku: „Zaloguj się” na ::before (wypełnia obrys po narysowaniu), „Dołącz…” na sobie, bo sam zmienia
   opacity. */
.login::before, .join {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 55%), var(--glass-tint);
  -webkit-backdrop-filter: blur(8px) saturate(1.5);
  backdrop-filter: blur(8px) saturate(1.5);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.26), inset 0 0 14px rgba(255, 255, 255, 0.06);
}
/* Tylko mysz: na ekranie dotykowym :hover zostaje po dotknięciu, także pod dialogiem i po jego zamknięciu. */
@media (hover: hover) {
  .login:hover .ico { transform: rotate(-8deg); }
  .join:hover .ico { transform: rotate(-24deg); }   /* klucz obraca się w zamku */
  .login:hover::before, .join:hover { background-color: rgba(10, 46, 56, 0.66); }
  .btn:not(:disabled):hover, .x:hover { background-color: rgba(255, 255, 255, 0.18); }
  .pri:not(:disabled):hover { background-color: #e3eceb; }
}

/* „Zaloguj się”: obrys rysuje się od góry w obie strony, potem wypełnia go szkło i wchodzi ikona z napisem. */
.login::before { content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; transition: opacity 480ms ease 520ms; }
.shown .login::before { opacity: 1; }
.shown .login .rim path { animation: stroke 760ms var(--draw) forwards; }
.login .face { opacity: 0; transform: translateY(6px); transition: opacity 360ms ease 520ms, transform 360ms var(--ease-out) 520ms; }
.shown .login .face { opacity: 1; transform: none; }

/* „Dołącz maszynę do floty”: staje pod spodem z gotową obwódką. */
.join { opacity: 0; transform: translateY(8px); transition: opacity 500ms ease 800ms, transform 500ms var(--ease-out) 800ms; }
.join .rim path { stroke-dashoffset: 0; }
.shown .join { opacity: 1; transform: none; }

/* Pod otwartym dialogiem panel i przyciski gasną (każde szkło samo, bez opacity na przodku), a po zamknięciu wracają
   przejściami z wejścia. */
.open .panel::before, .open .rim, .open .login::before, .open .face, .open .join {
  opacity: 0 !important;
  transition: opacity 200ms ease !important;
}

/* Dialog (showModal): przezroczysty na cały ekran, więc klik w sam <dialog> to klik w tło; szkło ma .sheet. */
.dlg {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 16px;
  border: 0;
  background: none;
  color: var(--ink);
  overflow: auto;
}
.dlg[open] { display: flex; }
.dlg::backdrop { background: rgba(4, 14, 16, 0.32); opacity: 0; transition: opacity 420ms ease; }
.dlg.in::backdrop { opacity: 1; }
.sheet {
  position: relative;
  width: min(400px, 100%);
  margin: auto;
  padding: 28px 28px 24px;
  border-radius: var(--r-pop);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 45%), rgba(8, 26, 32, 0.56);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.36), inset 0 0 24px rgba(255, 255, 255, 0.05);
  font: 400 15px/1.45 Plex, system-ui, -apple-system, "Segoe UI", sans-serif;
  opacity: 0;
  transform: translateY(12px) scale(0.96);
  transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
}
.in .sheet { opacity: 1; transform: none; }
.in .sheet .rim path { animation: stroke 640ms var(--draw) 80ms forwards; }
.x { position: absolute; top: 8px; right: 8px; width: 36px; height: 36px; padding: 6px; border: 0; border-radius: var(--r-ctl); background: none; color: rgba(255, 255, 255, 0.7); cursor: pointer; }
.x svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.locked .x { display: none; }
.body h2 { margin: 0 32px 10px 0; font-size: 21px; font-weight: 600; line-height: 1.25; }
.body p { margin: 0 0 14px; color: rgba(255, 255, 255, 0.84); }
.body .note { margin-top: 12px; font-size: 13px; color: rgba(255, 255, 255, 0.66); }
.tip, .err { padding: 10px 12px; border-radius: var(--r-ctl); background: rgba(255, 255, 255, 0.09); }
.body .err { background: rgba(255, 99, 99, 0.16); box-shadow: inset 3px 0 #ff6363; color: #ffd9d9; }
.err:empty { display: none; }

/* Przyciski dialogu: szkło jaśniejsze od arkusza, główny biały; Google według wytycznych marki (białe tło, obwódka
   #747775, napis #1f1f1f, „G” w czterech kolorach). */
.btn, .g {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 46px;
  margin-top: 10px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  background: rgba(255, 255, 255, 0.1);
  color: inherit;
  font: 600 15px/1.2 Plex, system-ui, sans-serif;
  text-decoration: none;
  cursor: pointer;
}
.pri { border-color: #fff; background: #fff; color: #0b1d20; }
.btn:disabled { opacity: 0.45; cursor: default; }
.g { border-color: #747775; background: #fff; color: #1f1f1f; }
.g svg { width: 20px; height: 20px; }

/* Pola: nazwa maszyny po przedrostku, kod 2FA, polecenie, sekret i kody zapasowe. */
.body label:not(.check) { display: block; margin-bottom: 6px; font-size: 13px; color: rgba(255, 255, 255, 0.72); }
.name, .code { border: 1px solid var(--line); border-radius: var(--r-ctl); background: var(--well); color: inherit; }
.name { display: flex; align-items: center; }
.name span, .name input, .code, .cmd, .secret, .codes { font: var(--mono); }
.name span { padding-left: 12px; color: rgba(255, 255, 255, 0.66); }
.name input { flex: 1; min-width: 0; height: 44px; padding: 0 12px 0 1px; border: 0; background: none; color: inherit; font-size: 16px; }   /* 16 px: iOS nie przybliża przy fokusie */
.name + .err { margin: 8px 0 0; }
.cmd { display: block; margin-top: 12px; padding: 10px 12px; border-radius: var(--r-ctl); background: var(--well); font-size: 13px; overflow-wrap: anywhere; user-select: all; }
.steps { margin: 16px 0 0; padding-left: 20px; font-size: 14px; color: rgba(255, 255, 255, 0.84); }
.steps li + li { margin-top: 4px; }
.code { width: 100%; height: 52px; padding: 0 12px; font-size: 22px; letter-spacing: 0.24em; text-align: center; }
.link { display: block; margin: 6px 0 0 auto; padding: 4px 0; border: 0; background: none; color: rgba(255, 255, 255, 0.84); font: inherit; font-size: 13px; text-decoration: underline; cursor: pointer; }
.check { display: flex; gap: 8px; align-items: center; margin-top: 14px; }
.check input { width: 18px; height: 18px; margin: 0; accent-color: #fff; }
.body .check + .note { margin: 2px 0 0 26px; }
.qr { display: block; width: 172px; height: 172px; margin: 0 auto 12px; border-radius: var(--r-ctl); background: #fff; shape-rendering: crispEdges; }
.pair { display: flex; gap: 10px; align-items: center; }
.pair .btn { width: auto; margin: 0; }
.secret { flex: 1; letter-spacing: 0.04em; }
.codes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 20px; margin: 0; padding: 12px 16px 12px 36px; border-radius: var(--r-ctl); background: var(--well); font-size: 16px; }

:is(.btn, .g, .x, .code, .check input):focus-visible, .name:focus-within { outline: 2px solid #fff; outline-offset: 2px; }
.sheet:focus, .name input { outline: none; }

/* Ruch ograniczony: nic się nie rusza, przejścia 1 ms, bez dryfu; panel i przyciski stają od razu po okładce. */
@media (prefers-reduced-motion: reduce) {
  .cover, .veil, .panel, .panel::before, .login::before, .login .face, .join, .ico, .rim, .sheet, .dlg::backdrop,
  .open .panel::before, .open .rim, .open .login::before, .open .face, .open .join {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }
  .drift .cover img, .rim path, .face::after { animation: none !important; }
  .framed .panel .rim path, .shown .login .rim path, .in .sheet .rim path { stroke-dashoffset: 0; }
  .cover, .login .face, .join, .cta:hover .ico, .sheet { transform: none; }
  .panel { transform: translate(-50%, -50%); }
}
