@font-face {
  font-family: "Encode Sans";
  src: url("../assets/fonts/EncodeSans-Variable.ttf") format("truetype");
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
}

:root {
  --bg-deep: #123329;
  --bg-mid: #1b5a45;
  --surface: rgba(255, 249, 240, 0.9);
  --surface-soft: rgba(255, 255, 255, 0.8);
  --surface-strong: rgba(255, 253, 247, 0.96);
  --ink: #173126;
  --muted: #557165;
  --accent: #189875;
  --accent-strong: #0f5d47;
  --gold: #f4bf57;
  --peach: #ff9166;
  --line: rgba(23, 49, 38, 0.12);
  --shadow: 0 30px 80px rgba(8, 31, 23, 0.22);
  --font-display: "Encode Sans", "Avenir Next", "Segoe UI", sans-serif;
  --font-body: "Encode Sans", "Avenir Next", "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

/* Backdrop art is the shared home/login background (AppChrome auth background),
   so the static legal pages read as the same place as the app. The portrait crop
   swaps in below AppLayout.bpMd (700px), matching
   AppChrome.prefersMobileBackground.

   `../brand/login-hall-bg{,-mobile}.webp` are hand COPIES of the app's real
   auth art, `packages/lucky_hall_ui/assets/backgrounds/loginbg{,_mobile}.webp`
   (a static page cannot reach into the Flutter asset bundle). Nothing syncs
   them, so they go stale silently: the pair sat at the pre-2026-09-22 scene for
   three days after the app's art was re-rendered. RE-COPY FROM THOSE TWO PATHS
   whenever the login background changes.

   BLUR AND TINT MIRROR THE APP, and the app owns the numbers — AuthShell paints
   pageGradientDecoration, then the art at AppChrome.arrivalBackdropBlurSigma,
   then pageBackdropScrimDecoration at AppChrome.pageBackdropScrimOpacity. Three
   layers, so three here:

     body                  the base gradient, AppColors.backgroundAlt ->
                           backgroundDark on the topLeft->bottomRight diagonal.
                           Also what overscroll and a not-yet-loaded art show.
     body::before          the ART, blurred 1.2px = arrivalBackdropBlurSigma.
                           CSS blur() takes a standard deviation, the same
                           quantity Flutter's ImageFilter.blur sigma is, so the
                           number transfers as written. The layer is inset 8px
                           PAST every edge because CSS samples transparent black
                           from outside an element and would fade the outermost
                           pixels; Flutter avoids that with TileMode.clamp, which
                           has no CSS equivalent. 8px clears a 1.2px sigma.
     body::after           the SCRIM. On web the app does not paint a flat wash:
                           the central two thirds hold 0.40 and both edges ramp
                           pageBackdropEdgeScrimBoost (0.20) darker over
                           pageBackdropEdgeScrimBand ((1 - 2/3)/2), on the
                           0.26/0.74 curve of AppChrome._ombreRamp. The stops
                           below are that ramp evaluated: 0.60 hard against each
                           side, 0.40 across the middle. Horizontal, matching
                           _ombreStops — it exists to sink the bare art a wide
                           window leaves down its sides.

   The art is pinned to the viewport on its own fixed layer rather than with
   `background-attachment: fixed`: mobile browsers either ignore `fixed` (iOS
   Safari) or repaint the page on every scroll frame and rescale the `cover` crop
   each time the URL bar collapses (Chrome Android), which reads as the backdrop
   jumping while scrolling. Both layers are sized to the large viewport (100lvh,
   100vh fallback) so the crop stays put while the browser chrome shows and
   hides.

   NOT mirrored: AppChrome.pageBackdropMinSize's 1440x810 scale floor (below it
   the app holds the art's scale and crops in; `cover` here keeps shrinking), and
   the app frames the art centred where these pages frame it `center top`. */
body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body);
  color: var(--ink);
  background: linear-gradient(to bottom right, #24543a 0%, #123222 100%);
}

body::before {
  content: "";
  position: fixed;
  top: -8px;
  left: -8px;
  z-index: -2;
  width: calc(100% + 16px);
  height: calc(100vh + 16px);
  height: calc(100lvh + 16px);
  pointer-events: none;
  background: url("../brand/login-hall-bg.webp") center top / cover no-repeat;
  filter: blur(1.2px);
}

@media (max-width: 699px) {
  body::before {
    background: url("../brand/login-hall-bg-mobile.webp") center top / cover
      no-repeat;
  }
}

body::after {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.6) 0%,
    rgba(0, 0, 0, 0.548) 5.556%,
    rgba(0, 0, 0, 0.452) 11.111%,
    rgba(0, 0, 0, 0.4) 16.667%,
    rgba(0, 0, 0, 0.4) 83.333%,
    rgba(0, 0, 0, 0.452) 88.889%,
    rgba(0, 0, 0, 0.548) 94.444%,
    rgba(0, 0, 0, 0.6) 100%
  );
}

main {
  width: min(1040px, calc(100vw - 32px));
  margin: 0 auto;
  padding: 40px 0 72px;
}

.hero {
  position: relative;
  padding: 24px 28px 24px;
  border: 1px solid rgba(255, 241, 212, 0.16);
  border-radius: 30px;
  background: rgba(16, 59, 47, 0.96);
  box-shadow: 0 24px 54px rgba(8, 31, 23, 0.18);
  overflow: hidden;
  isolation: isolate;
  animation: fade-up 700ms ease both;
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0)),
    radial-gradient(circle at 84% 16%, rgba(244, 191, 87, 0.08), transparent 16%);
  z-index: -1;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(260px, 0.75fr);
  gap: 24px;
  align-items: center;
}

h1,
h2 {
  margin: 0;
  font-family: var(--font-display);
  letter-spacing: -0.02em;
}

h1 {
  margin-top: 0;
  font-size: clamp(2.35rem, 4.8vw, 4rem);
  max-width: 11ch;
  line-height: 1.02;
  color: #e3b62f;
  text-wrap: balance;
}

.hero-copy {
  margin-top: 10px;
  max-width: 58ch;
  color: rgba(255, 246, 232, 0.78);
  font-size: 0.98rem;
  line-height: 1.65;
}

.hero-kicker {
  margin: 14px 0 0;
  color: rgba(255, 246, 232, 0.92);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.hero-copy-group {
  align-self: center;
  padding-right: 12px;
}

.hero-art {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  padding: 4px 18px 12px;
  background: none;
}

.hero-logo {
  position: relative;
  width: clamp(210px, 74%, 300px);
  height: auto;
  opacity: 0.98;
  filter: drop-shadow(0 14px 20px rgba(6, 24, 18, 0.18));
}

.doc-shell {
  margin-top: 22px;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: 24px;
  background: var(--surface-strong);
  box-shadow: 0 14px 24px rgba(24, 39, 31, 0.08);
  animation: fade-up 820ms ease both;
}

.document-updated {
  margin: 0;
  color: var(--accent-strong);
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.status {
  margin: 10px 0 0;
  color: var(--muted);
  line-height: 1.6;
}

.status.error {
  color: #8b3a31;
}

.document {
  display: grid;
  gap: 14px;
  margin-top: 20px;
}

.section-card {
  padding: 20px 22px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid var(--line);
  box-shadow: 0 8px 18px rgba(8, 31, 23, 0.04);
  animation: fade-up 700ms ease both;
  animation-delay: calc(var(--section-index, 0) * 65ms);
}

.section-card h2 {
  font-size: clamp(1.2rem, 1.8vw, 1.55rem);
  margin-bottom: 10px;
}

.section-card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.97rem;
  line-height: 1.65;
}

.section-card p + p {
  margin-top: 12px;
}

.loading {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.loading::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(13, 105, 79, 0.18);
  border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}

.support-panel {
  margin-top: 24px;
  padding: 24px;
  border-radius: 20px;
  background: rgba(255, 251, 245, 0.96);
  border: 1px solid rgba(23, 49, 38, 0.1);
  box-shadow: 0 10px 20px rgba(8, 31, 23, 0.05);
  animation: fade-up 900ms ease both;
}

.support-panel h2 {
  font-size: clamp(1.15rem, 1.8vw, 1.5rem);
  margin-bottom: 10px;
}

.support-panel p {
  margin: 0;
  color: var(--muted);
  font-size: 0.97rem;
  line-height: 1.65;
}

.support-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  margin-top: 18px;
  padding: 0 16px;
  border-radius: 12px;
  background: rgba(15, 93, 71, 0.08);
  border: 1px solid rgba(15, 93, 71, 0.18);
  color: var(--accent-strong);
  font-weight: 700;
  text-decoration: none;
  box-shadow: none;
}

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(20px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Phone layout: the panels run edge to edge (no side gutter, outer radius,
   or side borders) so the backdrop never shows beside them, and the inner
   padding is trimmed so the copy gets the screen width. */
@media (max-width: 760px) {
  main {
    width: 100%;
    padding: 18px 0 34px;
  }

  .hero-grid {
    grid-template-columns: 1fr;
  }

  .hero,
  .doc-shell,
  .support-panel {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }

  .hero {
    padding: 20px 16px;
  }

  .hero-copy-group {
    padding-right: 0;
  }

  .doc-shell,
  .support-panel {
    padding: 16px 14px;
  }

  .section-card {
    padding: 16px 14px;
  }

  /* Stacked hero: the logo leads, then the title and copy, all centred
     under it (owner call 2026-09-19); the side-by-side desktop hero keeps
     its left-aligned text. */
  .hero-art {
    order: -1;
    min-height: 210px;
  }

  .hero-copy-group {
    text-align: center;
  }

  h1,
  .hero-copy {
    margin-left: auto;
    margin-right: auto;
  }
}
