/* The opening.

   A single line wipes in from the left on a pale gradient, holds, then the
   whole card fades away to reveal the opening screen underneath: pill nav at
   the top, one very large centred line, a subhead and a single dark button.

   The intro never blocks the page: it is inert to pointer events after it
   fades, it is skipped entirely under reduced motion, and the screen beneath
   it is fully rendered the whole time, so a failed script leaves a correct
   page rather than a blank one. */

.intro {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: linear-gradient(180deg, #d9d9d9 0%, #e9e9e9 34%, #f7f7f7 72%, #ffffff 100%);
  transition: opacity .9s cubic-bezier(.4,0,.2,1), visibility 0s linear .9s;
}
.intro.is-gone { opacity: 0; visibility: hidden; pointer-events: none; }
/* FAILSAFE: the overlay also retires itself, so a module that never loads cannot
   leave the page blank behind it. site.js clears it at 1.6s, well before this
   starts, and once .is-gone is set the animation runs from 0 to 0 and shows
   nothing. Only a page whose script never ran ever sees it. */
.intro { animation: introOut .9s cubic-bezier(.4,0,.2,1) 3s forwards; }
@keyframes introOut { to { opacity: 0; visibility: hidden; pointer-events: none; } }
.intro p {
  margin: 0; font-family: var(--display);
  font-size: clamp(15px, 1.35vw, 19px); font-weight: 500; letter-spacing: -.02em; color: #17191d; /* the logo mark, in graphite */
  /* wipes in left to right (user, 2026-09-22: "add the fade back its missing") */
  -webkit-mask-image: linear-gradient(90deg, #000 0 72%, transparent 100%); mask-image: linear-gradient(90deg, #000 0 72%, transparent 100%);
  -webkit-mask-size: 0% 100%; mask-size: 0% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  animation: wipe 1s cubic-bezier(.22,.61,.36,1) .15s forwards;
}
/* the mask's soft tail gives the wipe a feathered edge (a gradient, not a blur);
   140% puts the solid part (72% of it) past the right edge at the end */
@keyframes wipe { to { -webkit-mask-size: 140% 100%; mask-size: 140% 100%; } }

/* The opening screen: a dark, Linear-style hero over a drifting monochrome light
   field served as HLS. Built to the Datacore brief in black, grey and white in place of its
   purple and orange, and Seen's own words. */
.open-screen {
  --o-accent: #f2f3f5;     /* the primary, on a near-black screen, so it is near-white */
  --o-accent-2: #b6bac1;  /* the secondary accent, a light neutral on the dark screen */
  --o-ground: #0b0c0e;   /* the same as the section that follows, so the join has nothing to show */
  /* no overflow clip: it only held the film, and its anti-aliased bottom edge let the
     white curtain behind show as a hairline at fractional display scaling */
  position: relative;
  min-height: 100svh; display: grid; align-content: center; justify-items: center; text-align: center;
  padding: calc(var(--nav-h, 64px) + 24px) var(--gutter, 24px) clamp(40px, 6vh, 64px);
  background: var(--o-ground); color: #f4f5f7;
  font-family: var(--sans);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);   /* the curtain's top hairline */
}


.open-inner { display: grid; justify-items: center; }

/* the glass pill */
.open-badge {
  display: inline-flex; align-items: center; gap: 10px;
  height: 34px; padding: 0 12px 0 4px; margin-bottom: clamp(30px, 4.6vh, 50px);
  border-radius: 999px; border: 1px solid rgba(255,255,255,.13);
  background: rgba(255,255,255,.06);
  backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
  font-family: var(--sans); font-size: 13.5px; font-weight: 500; color: rgba(237,238,240,.86);
  transition: background .22s ease, border-color .22s ease, backdrop-filter .22s ease, transform .22s cubic-bezier(.2,.7,.2,1);
}
.open-badge:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); backdrop-filter: blur(9px) saturate(185%); -webkit-backdrop-filter: blur(9px) saturate(185%); }
.open-badge-tag {
  display: inline-flex; align-items: center; height: 26px; padding: 0 10px; border-radius: 999px;
  background: var(--o-accent); color: #0b0c0e;
  font-family: var(--sans); font-size: 12px; font-weight: 600; letter-spacing: .02em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28);
}
.open-badge svg { width: 14px; height: 14px; color: var(--o-accent-2); transition: transform .22s cubic-bezier(.2,.7,.2,1); }
.open-badge:hover svg { transform: translateX(2px); }

/* the headline: Geist 700, like every major heading on the site */
.open-screen h1 {
  margin: -.1em -.05em; padding: .1em .05em;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(34px, 6.4vw, 92px); line-height: .96; letter-spacing: -.04em;
  /* "Spottr. Find the company behind it." does not hold one line at any width the
     shell allows, so it wraps and balances instead of being pinned with nowrap,
     which overflowed the document by ~300px at 1440. */
  white-space: normal; text-wrap: balance; max-width: 17ch;
}
/* each half keeps the tone it had as two lines: "See it." white, "Own it." the softer mid-grey */
.open-screen h1 span {
  display: inline-block; padding-bottom: .08em;
  background: #ffffff; -webkit-background-clip: text; background-clip: text; color: transparent;
}
.open-screen h1 span + span {
  margin-left: .26em;
  background: linear-gradient(180deg, rgba(236,237,239,.9) 0%, rgba(217,219,223,.74) 100%);
  -webkit-background-clip: text; background-clip: text;
}

.open-screen .open-sub {
  margin: clamp(26px, 3.6vh, 40px) 0 0; max-width: 46ch;
  font-size: clamp(15px, 1.3vw, 18.5px); line-height: 1.55; letter-spacing: -.005em; color: rgba(221,223,226,.66);
}

/* the two buttons: light primary, dark glass secondary */
.open-ctas { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: clamp(34px, 5vh, 54px); }
.open-cta {
  display: inline-flex; align-items: center; gap: 8px; height: 48px; padding: 0 22px; border-radius: 12px;
  font-family: var(--sans); font-size: 15.5px; font-weight: 600; letter-spacing: -.005em;
  transition: transform .22s cubic-bezier(.2,.7,.2,1), background .22s ease, border-color .22s ease, box-shadow .22s ease, filter .22s ease, backdrop-filter .22s ease;
}
.open-cta svg { width: 16px; height: 16px; transition: transform .22s cubic-bezier(.2,.7,.2,1); }
.open-cta-primary {
  background: var(--o-accent); color: #0b0c0e;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.26), 0 0 0 1px rgba(242,243,245,.5);
}
.open-cta-primary:hover { transform: scale(1.035); filter: brightness(1.1); }
.open-cta-primary:hover svg { transform: translateX(2px); }

/* The opening screen's text rises out of a line (user, 2026-09-22: "add animation to
   the text too", after "text fade in is bad"): no opacity fade and no blur. Each piece
   is clipped from the bottom and slides up as the clip opens, so it reads as coming
   up from behind a slot. .text-in is added by site.js as the dissolve settles, or when
   the screen is scrolled into view by hand. The final clip is inset with negative
   margins so hover scales and descenders are never cut. */
.open-badge, .open-screen h1 span, .open-screen .open-sub, .open-cta {
  clip-path: inset(0 0 100% 0); transform: translateY(.6em);
}
.open-screen.text-in .open-badge, .open-screen.text-in h1 span, .open-screen.text-in .open-sub, .open-screen.text-in .open-cta {
  animation: riseLine .95s cubic-bezier(.16,1,.3,1) both;
}
.open-screen.text-in .open-badge { animation-delay: 0s; }
.open-screen.text-in h1 span:first-child { animation-delay: .08s; }
.open-screen.text-in h1 span + span { animation-delay: .2s; }
.open-screen.text-in .open-sub { animation-delay: .34s; }
.open-screen.text-in .open-cta-primary { animation-delay: .46s; }
.open-screen.text-in .open-cta-apk { animation-delay: .54s; }
@keyframes riseLine {
  from { clip-path: inset(0 0 100% 0); transform: translateY(.6em); }
  to { clip-path: inset(-30% -12% -30% -12%); transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .open-badge, .open-screen h1 span, .open-screen .open-sub, .open-cta { clip-path: none; transform: none; animation: none !important; }
}


/* The two-part headline is too long to hold one line on a narrow screen, where
   a two-word headline did. Below this width the two halves stack instead of
   running off the side, and each keeps its own tone. */
@media (max-width: 820px) {
  .open-screen h1 { max-width: none; }
  .open-screen h1 span { display: block; }
  .open-screen h1 span + span { margin-left: 0; }
}

@media (max-width: 560px) {
  .open-cta { height: 46px; padding: 0 18px; font-size: 15px; }
  .open-screen h1 { font-size: 15vw; }
  .open-screen .open-sub { font-size: 15.5px; }
  .open-ctas { width: 100%; }
  .open-cta { flex: 1 1 auto; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }
  .intro p { -webkit-mask-image: none; mask-image: none; animation: none; }
}


/* the Android robot on the APK buttons */
.open-cta-apk .android-mark { width: 18px; height: 18px; }
