/* ============================================================================
   PWA front end — install modal, iOS guide, splash, update toast.

   Colours come from the page's own custom properties where they exist so the
   dialog inherits whatever theme the admin picked, with hard fallbacks for the
   marketing pages that do not load the panel palette.
   ============================================================================ */

/* ------------------------------------------------------------- backdrop */
.fs-pwa-back {
  position: fixed; inset: 0; z-index: 99999;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 16px;
  background: rgba(9, 12, 24, .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .22s ease;
}
.fs-pwa-back.is-on { opacity: 1; }
@media (min-width: 640px) { .fs-pwa-back { align-items: center; } }

/* --------------------------------------------------------------- modal */
.fs-pwa-modal {
  position: relative; width: 100%; max-width: 430px;
  padding: 24px 22px 20px; border-radius: 22px;
  background: rgba(255, 255, 255, .94);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
  border: 1px solid rgba(255, 255, 255, .6);
  box-shadow: 0 24px 60px -18px rgba(9, 12, 24, .5),
              0 2px 8px rgba(9, 12, 24, .12);
  color: #0f172a;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  transform: translateY(18px) scale(.98);
  transition: transform .26s cubic-bezier(.22, 1, .36, 1);
}
.fs-pwa-back.is-on .fs-pwa-modal { transform: none; }

.fs-pwa-x {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: rgba(15, 23, 42, .06); color: #475569;
  font-size: 19px; line-height: 1; cursor: pointer;
  transition: background .15s, color .15s;
}
.fs-pwa-x:hover { background: rgba(15, 23, 42, .12); color: #0f172a; }

.fs-pwa-top { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.fs-pwa-icon {
  flex: 0 0 56px; width: 56px; height: 56px; border-radius: 14px; object-fit: cover;
  box-shadow: 0 4px 14px -4px rgba(9, 12, 24, .4);
}
.fs-pwa-h { display: block; font-size: 1.06rem; font-weight: 750; letter-spacing: -.01em;
            line-height: 1.3; margin-bottom: 4px; }
.fs-pwa-p { margin: 0; font-size: .875rem; line-height: 1.55; color: #475569; }

/* ------------------------------------------------------------ benefits */
.fs-pwa-benefits { list-style: none; margin: 0 0 18px; padding: 0; }
.fs-pwa-benefits li {
  position: relative; padding: 5px 0 5px 26px;
  font-size: .855rem; line-height: 1.5; color: #334155;
}
.fs-pwa-benefits li::before {
  content: ''; position: absolute; left: 4px; top: 10px;
  width: 11px; height: 6px; border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); color: #10b981;
}

/* --------------------------------------------------------- iOS steps */
.fs-pwa-steps { margin: 0 0 18px; padding: 0; list-style: none; counter-reset: s; }
.fs-pwa-steps li {
  counter-increment: s; position: relative; padding: 8px 0 8px 34px;
  font-size: .87rem; line-height: 1.5; color: #334155;
  border-bottom: 1px solid rgba(15, 23, 42, .07);
}
.fs-pwa-steps li:last-child { border-bottom: 0; }
.fs-pwa-steps li::before {
  content: counter(s); position: absolute; left: 0; top: 8px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--primary, #4f46e5); color: #fff;
  font-size: .72rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

/* -------------------------------------------------------------- buttons */
.fs-pwa-actions { display: flex; gap: 9px; }
.fs-pwa-btn {
  flex: 1; appearance: none; border: 1px solid rgba(15, 23, 42, .12);
  background: #fff; color: #0f172a; cursor: pointer;
  padding: 12px 16px; border-radius: 12px;
  font: inherit; font-size: .9rem; font-weight: 650;
  transition: transform .15s ease, filter .15s ease, border-color .15s ease;
}
.fs-pwa-btn:hover { transform: translateY(-1px); border-color: rgba(15, 23, 42, .22); }
.fs-pwa-btn:active { transform: translateY(0); }
.fs-pwa-btn--primary {
  background: var(--primary, #4f46e5); border-color: transparent; color: #fff;
  box-shadow: 0 6px 18px -6px rgba(79, 70, 229, .6);
}
.fs-pwa-btn--primary:hover { filter: brightness(1.07); }
.fs-pwa-btn:focus-visible { outline: 2px solid var(--primary, #4f46e5); outline-offset: 2px; }

.fs-pwa-never {
  display: block; width: 100%; margin-top: 12px; padding: 6px;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .78rem; color: #94a3b8;
}
.fs-pwa-never:hover { color: #64748b; text-decoration: underline; }

/* --------------------------------------------------------- update toast */
.fs-pwa-update {
  position: fixed; z-index: 99998; left: 16px; right: 16px; bottom: 16px;
  display: flex; flex-wrap: wrap; gap: 12px;
  align-items: center; justify-content: space-between;
  padding: 14px 16px; border-radius: 16px;
  background: rgba(15, 23, 42, .94);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: #fff; box-shadow: 0 18px 40px -14px rgba(9, 12, 24, .7);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  opacity: 0; transform: translateY(14px); transition: opacity .22s, transform .22s;
}
.fs-pwa-update.is-on { opacity: 1; transform: none; }
.fs-pwa-update b { display: block; font-size: .92rem; font-weight: 700; }
.fs-pwa-update span { display: block; font-size: .8rem; color: rgba(255, 255, 255, .72); margin-top: 2px; }
.fs-pwa-update__a { display: flex; gap: 8px; }
.fs-pwa-update .fs-pwa-btn { flex: 0 0 auto; padding: 9px 16px; font-size: .85rem;
  background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .18); color: #fff; }
.fs-pwa-update .fs-pwa-btn--primary { background: var(--primary, #4f46e5); border-color: transparent; }
@media (min-width: 640px) { .fs-pwa-update { left: auto; right: 20px; max-width: 480px; } }

/* -------------------------------------------------------------- splash
   Reworked. The old version looped the logo animation forever (fade, pulse,
   scale or spin), which reads as "still loading" rather than as branding —
   a logo that never stops moving is a spinner wearing a logo. A launch screen
   should introduce itself once and then hold still while a separate, quiet
   indicator carries the waiting.

   So: the mark arrives once, settles, and a hairline progress bar underneath
   does the work of showing that something is happening. */
.fs-pwa-splash {
  position: fixed; inset: 0; z-index: 100000;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0; color: #fff; text-align: center;
  padding: env(safe-area-inset-top, 0) env(safe-area-inset-right, 0)
           env(safe-area-inset-bottom, 0) env(safe-area-inset-left, 0);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* Exit is a fade with the faintest lift, so the panel appears to come
     forward rather than the splash simply vanishing. */
  transition: opacity .34s ease, transform .34s ease;
  will-change: opacity;
}
/* A flat fill looks like a placeholder. Two very soft pools of light, tinted
   from the brand colour, give it depth without costing a paint — both are
   radial gradients on the same layer, no blur filter. */
.fs-pwa-splash::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(58% 42% at 50% 32%, rgba(255,255,255,.10), transparent 70%),
    radial-gradient(48% 38% at 50% 88%, rgba(255,255,255,.055), transparent 72%);
}
.fs-pwa-splash.is-out { opacity: 0; transform: scale(1.015); pointer-events: none; }

.fs-pwa-splash__in {
  position: relative; display: flex; flex-direction: column;
  align-items: center; gap: 14px;
}

.fs-pwa-splash img {
  width: 76px; height: 76px; border-radius: 21px; object-fit: cover;
  /* iOS-style squircle shadow: tight, low, no spread — it reads as a real app
     icon sitting on the surface rather than a floating picture. */
  box-shadow: 0 10px 26px -10px rgba(0,0,0,.55), 0 1px 0 rgba(255,255,255,.14) inset;
  animation: fsMark .52s cubic-bezier(.2,.7,.3,1) both;
}
/* One entrance, then still. The 1% breathing that follows is deliberately at
   the edge of perception — enough that the screen is not frozen, not enough
   to read as motion. */
.fs-pwa-splash img { animation: fsMark .52s cubic-bezier(.2,.7,.3,1) both,
                                fsBreathe 4.2s ease-in-out 1s infinite; }

.fs-pwa-splash b {
  font-size: 1.22rem; font-weight: 700; letter-spacing: -.022em; line-height: 1;
  animation: fsRise .5s cubic-bezier(.2,.7,.3,1) .09s both;
}
.fs-pwa-splash span {
  font-size: .845rem; opacity: .62; letter-spacing: -.005em;
  animation: fsRise .5s cubic-bezier(.2,.7,.3,1) .15s both;
}

/* Hairline indeterminate bar. This is what tells the user the app is working;
   it is 2px so it never competes with the mark. */
.fs-pwa-splash__bar {
  position: relative; width: 116px; height: 2px; border-radius: 2px; margin-top: 6px;
  background: rgba(255,255,255,.16); overflow: hidden;
  animation: fsRise .5s cubic-bezier(.2,.7,.3,1) .22s both;
}
.fs-pwa-splash__bar::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.92), transparent);
  transform: translateX(-100%);
  animation: fsSweep 1.35s cubic-bezier(.5,0,.5,1) infinite;
}

.fs-pwa-splash em {
  position: absolute; left: 0; right: 0; bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  font-style: normal; font-size: .7rem; opacity: .34; letter-spacing: .01em;
}

@keyframes fsMark    { from { opacity: 0; transform: scale(.86) translateY(6px) } to { opacity: 1; transform: none } }
@keyframes fsBreathe { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.012) } }
@keyframes fsRise    { from { opacity: 0; transform: translateY(7px) } to { opacity: 1; transform: none } }
@keyframes fsSweep   { to { transform: translateX(100%) } }

/* The four anim_ options in the admin used to pick a looping logo animation.
   They now choose how the whole screen leaves, which is the part a user
   actually perceives — the entrance is the same either way. */
.fs-pwa-splash.anim-scale.is-out   { transform: scale(1.045); }
.fs-pwa-splash.anim-pulse.is-out   { transform: scale(.985); }
.fs-pwa-splash.anim-spinner.is-out { transform: scale(1.015); }

/* Light splash colour. The background is admin-set, so a pale value is
   allowed — but the type on it is white, and on a pale background that is an
   invisible launch screen. The inline paint measures the luminance and tags
   the element; everything ink-coloured flips here. */
.fs-pwa-splash.is-light { color: #0f172a; }
.fs-pwa-splash.is-light::before {
  background:
    radial-gradient(58% 42% at 50% 32%, rgba(0,0,0,.055), transparent 70%),
    radial-gradient(48% 38% at 50% 88%, rgba(0,0,0,.03), transparent 72%);
}
.fs-pwa-splash.is-light img {
  box-shadow: 0 10px 26px -12px rgba(15,23,42,.32), 0 0 0 1px rgba(15,23,42,.06);
}
.fs-pwa-splash.is-light .fs-pwa-splash__bar { background: rgba(15,23,42,.14); }
.fs-pwa-splash.is-light .fs-pwa-splash__bar::after {
  background: linear-gradient(90deg, transparent, rgba(15,23,42,.6), transparent);
}

/* --------------------------------------------------------- dark scheme */
@media (prefers-color-scheme: dark) {
  .fs-pwa-modal { background: rgba(23, 29, 45, .95); border-color: rgba(255, 255, 255, .1); color: #e8edf7; }
  .fs-pwa-p, .fs-pwa-benefits li, .fs-pwa-steps li { color: #b6c0d4; }
  .fs-pwa-steps li { border-bottom-color: rgba(255, 255, 255, .09); }
  .fs-pwa-btn { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .14); color: #e8edf7; }
  .fs-pwa-x { background: rgba(255, 255, 255, .09); color: #cbd5e1; }
}

/* Motion is decoration here; the dialog still opens and closes without it.
   On the splash everything is dropped except the sweep on the progress bar —
   with no motion at all the screen is indistinguishable from a frozen app,
   and a 2px line is not what "reduce motion" is asking to be spared. */
@media (prefers-reduced-motion: reduce) {
  .fs-pwa-back, .fs-pwa-modal, .fs-pwa-update { transition: none; }
  .fs-pwa-modal { transform: none; }
  .fs-pwa-splash,
  .fs-pwa-splash img,
  .fs-pwa-splash b,
  .fs-pwa-splash span,
  .fs-pwa-splash__bar { animation: none !important; transition: opacity .2s ease !important; }
  .fs-pwa-splash.is-out { transform: none !important; }
}
