/*
 * The screen for opening Tabs with no connection. Two places use it:
 * public/offline.html, which the service worker (public/sw.js) serves when
 * the browser can't load the app at all, and OfflineStart
 * (src/components/shared/offline-start.tsx), when the app loaded but the
 * device is offline (the desktop app, or a page the browser had kept).
 * Plain CSS with its own tokens, like boot-loader.css: offline.html has
 * nothing else to lean on. Sizes are px because the app scales its rem.
 *
 * A shop's door sign, shaped like a folder tab, hangs from a nail and
 * swings a little. It reads OFFLINE; when the connection is back it flips
 * over to OPEN (.is-back) and the app opens.
 *
 * Brand colours, flat (web/docs/design/DESIGN_SYSTEM.md 6): the sign is
 * gamboge while it waits and mint once it's open, in both themes, on
 * paper. No shadows and no gradients; the swing and the flip are all the
 * life it needs.
 */

.tabs-offline {
  --tabs-offline-bg: #ebebeb;
  --tabs-offline-fg: #292929;
  --tabs-offline-muted: #5b6472;
  --tabs-offline-string: #292929;
  --tabs-offline-sign: #f29a13;
  --tabs-offline-open: #04e2c1;
  /* Ink, on both faces and in both themes: the sign keeps its colours. */
  --tabs-offline-sign-ink: #292929;
  --tabs-offline-waiting: #f29a13;
  --tabs-offline-checking: #2a96c8;
  --tabs-offline-back: #04e2c1;
  /* The app's primary button: deep blue in light, mint in dark. */
  --tabs-offline-button: #1b7aa7;
  --tabs-offline-button-ink: #ffffff;

  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
  text-align: center;
  color: var(--tabs-offline-fg);
  font-family:
    ui-sans-serif,
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  background: var(--tabs-offline-bg);
}

html.dark .tabs-offline {
  --tabs-offline-bg: #090d15;
  --tabs-offline-fg: #ebf0f4;
  --tabs-offline-muted: #9dabbe;
  --tabs-offline-string: #9dabbe;
  --tabs-offline-button: #04e2c1;
  --tabs-offline-button-ink: #292929;
}

/* The nail, the strings and the sign. */
.tabs-offline__scene {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 36px;
  animation: tabs-offline-up 500ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.tabs-offline__nail {
  position: relative;
  z-index: 1;
  width: 12px;
  height: 12px;
  margin-bottom: -6px;
  border-radius: 999px;
  background: var(--tabs-offline-string);
}

.tabs-offline__hang {
  display: flex;
  flex-direction: column;
  align-items: center;
  transform-origin: 50% 0;
  perspective: 700px;
  animation: tabs-offline-swing 3.2s ease-in-out infinite;
}

.tabs-offline__strings {
  /* Over the sign, so each string runs down into its eyelet. */
  position: relative;
  z-index: 2;
  display: block;
  width: 200px;
  height: 60px;
  overflow: visible;
  stroke: var(--tabs-offline-string);
  stroke-width: 2;
  stroke-linecap: round;
  fill: none;
}

.tabs-offline__sign {
  position: relative;
  width: 200px;
  height: 112px;
  transform-style: preserve-3d;
  transition: transform 700ms cubic-bezier(0.3, 1.35, 0.5, 1);
}

.tabs-offline__face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border-radius: 6px 14px 14px 14px;
  background: var(--tabs-offline-sign);
  color: var(--tabs-offline-sign-ink);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* The folder tab along the top, which the left string holds. */
.tabs-offline__face::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 0;
  width: 44%;
  height: 14px;
  border-radius: 10px 10px 0 0;
  background: inherit;
}

/* A painted border just inside the edge. */
.tabs-offline__face::after {
  content: "";
  position: absolute;
  inset: 7px;
  border: 2px dotted rgb(41 41 41 / 0.45);
  border-radius: 8px;
  pointer-events: none;
}

/* The eyelets the strings go through. */
.tabs-offline__eyelet {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--tabs-offline-bg);
  outline: 2px solid var(--tabs-offline-sign-ink);
}

.tabs-offline__eyelet--left {
  top: -8px;
  left: calc(26% - 3.5px);
}

.tabs-offline__eyelet--right {
  top: 6px;
  left: calc(85% - 3.5px);
}

.tabs-offline__word {
  font-size: 26px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.22em;
  /* Letter spacing trails the last letter; this puts the word back in the
     middle. */
  margin-right: -0.22em;
  text-transform: uppercase;
}

.tabs-offline__small {
  font-size: 14px;
  font-style: italic;
  font-weight: 600;
}

/* The other side, turned away until the flip. Its folder tab and eyelets
   are mirrored so they land in the same place once it faces front. */
.tabs-offline__face--back {
  transform: rotateY(180deg);
  border-radius: 14px 6px 14px 14px;
  background: var(--tabs-offline-open);
}

.tabs-offline__face--back::before {
  left: auto;
  right: 0;
}

.tabs-offline__face--back .tabs-offline__eyelet--left {
  left: auto;
  right: calc(26% - 3.5px);
}

.tabs-offline__face--back .tabs-offline__eyelet--right {
  left: auto;
  right: calc(85% - 3.5px);
}

.tabs-offline.is-back .tabs-offline__hang {
  animation: none;
}

.tabs-offline.is-back .tabs-offline__sign {
  transform: rotateY(180deg);
}

/* The words under the sign. */
.tabs-offline__title {
  margin: 0;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.03em;
  animation: tabs-offline-up 500ms cubic-bezier(0.2, 0.8, 0.2, 1) 60ms both;
}

.tabs-offline__body {
  max-width: 320px;
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tabs-offline-muted);
  animation: tabs-offline-up 500ms cubic-bezier(0.2, 0.8, 0.2, 1) 120ms both;
}

.tabs-offline__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 20px;
  margin: 20px 0 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--tabs-offline-muted);
  animation: tabs-offline-up 500ms cubic-bezier(0.2, 0.8, 0.2, 1) 180ms both;
}

.tabs-offline__dot {
  position: relative;
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 999px;
  background: var(--tabs-offline-waiting);
}

.tabs-offline__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: inherit;
  animation: tabs-offline-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}

.tabs-offline.is-checking .tabs-offline__dot {
  background: var(--tabs-offline-checking);
}

.tabs-offline.is-checking .tabs-offline__dot::after {
  animation-duration: 0.8s;
}

.tabs-offline.is-back .tabs-offline__dot {
  background: var(--tabs-offline-back);
}

.tabs-offline.is-back .tabs-offline__dot::after {
  animation: none;
}

.tabs-offline__retry {
  display: inline-flex;
  align-items: center;
  height: 36px;
  margin-top: 16px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: var(--tabs-offline-button);
  color: var(--tabs-offline-button-ink);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: opacity 150ms;
  animation: tabs-offline-up 500ms cubic-bezier(0.2, 0.8, 0.2, 1) 240ms both;
}

.tabs-offline__retry:hover:not(:disabled) {
  opacity: 0.9;
}

.tabs-offline__retry:focus-visible {
  outline: 2px solid var(--tabs-offline-fg);
  outline-offset: 2px;
}

.tabs-offline__retry:disabled {
  cursor: default;
  opacity: 0.6;
}

.tabs-offline.is-back .tabs-offline__retry {
  visibility: hidden;
}

@keyframes tabs-offline-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@keyframes tabs-offline-swing {
  0%,
  100% {
    transform: rotate(-3deg);
  }
  50% {
    transform: rotate(3deg);
  }
}

@keyframes tabs-offline-ping {
  75%,
  100% {
    opacity: 0;
    transform: scale(2.4);
  }
}

/* Still, and the flip becomes a crossfade. */
@media (prefers-reduced-motion: reduce) {
  .tabs-offline__scene,
  .tabs-offline__title,
  .tabs-offline__body,
  .tabs-offline__status,
  .tabs-offline__retry,
  .tabs-offline__hang,
  .tabs-offline__dot::after {
    animation: none;
  }

  .tabs-offline__sign,
  .tabs-offline.is-back .tabs-offline__sign {
    transform: none;
    transition: none;
  }

  .tabs-offline__face {
    transition: opacity 300ms;
  }

  .tabs-offline__face--back {
    transform: none;
    border-radius: 6px 14px 14px 14px;
    opacity: 0;
  }

  .tabs-offline__face--back::before {
    left: 0;
    right: auto;
  }

  .tabs-offline__face--back .tabs-offline__eyelet--left {
    left: calc(26% - 3.5px);
    right: auto;
  }

  .tabs-offline__face--back .tabs-offline__eyelet--right {
    left: calc(85% - 3.5px);
    right: auto;
  }

  .tabs-offline.is-back .tabs-offline__face--front {
    opacity: 0;
  }

  .tabs-offline.is-back .tabs-offline__face--back {
    opacity: 1;
  }
}
