@import url("tokens.css");
@import url("shell.css");

/* ============================================================================
   Native Apps Team — site.css
   Design system + homepage. Vanilla CSS, no build step, no external requests.

   Contract: every colour / size / easing value comes from assets/tokens.css.
   Anything defined here is ADDITIVE (a derived value or a component style) —
   token names are never redefined at :root.

   THE SHELL IS NOT HERE. Reset, base type, .wrap, the skip link, the sticky
   nav, .pill and the footer live in assets/shell.css and are shared with the
   document pages through assets/legal.css. Never re-declare any of them in
   this file — the two stylesheets must stay one shell.
   (Both @import rules must remain above every other rule here.)

   Sections
     1  Additive vars
     3  Typography
     4  Layout primitives
     5  Motion (reveal + pin) — all gated on html.js and no-preference
     7  App Store badge
     8  Hero
     9  App sections + product modules   ← the repeatable multi-app pattern
    10  Plans (free vs Pro)
    11  Mid CTA
    12  Studio app rail
    13  Support / FAQ (legacy markup, restyled)
    14  About
   ========================================================================= */


/* ── 1. Additive vars ──────────────────────────────────────────────────────
   --bar-h, --accent, --dur-fast and --ease-quint come from shell.css.
   Only homepage-specific derivations belong here. */
:root{
  /* Dark surface used by the one inverted band. Fixed, not theme-dependent. */
  --band:#0A0A0C;
}


/* ── 3. Typography ─────────────────────────────────────────────────────── */
h1,.t-hero{
  font-size:var(--t-hero);
  line-height:1.02;
  letter-spacing:-.028em;
}
h2,.t-h2{
  font-size:var(--t-h2);
  line-height:1.06;
  letter-spacing:-.022em;
}
h3,.t-h3{
  font-size:var(--t-h3);
  line-height:1.16;
  letter-spacing:-.014em;
}
/* Measure caps live on the text elements themselves, never on their
   containers: `ch` resolves against the element's own font-size, so 20ch on
   a 96px headline is ~1100px while 20ch on a wrapper would be ~190px. */
.lead{
  font-size:var(--t-lead);
  line-height:1.45;
  letter-spacing:-.014em;
  color:var(--ink-2);
  max-width:38ch;
}
.eyebrow{
  font-size:var(--t-cap);
  font-weight:600;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--accent);
  margin-bottom:var(--s-1);
}
/* --ink-3 is only 3.5:1 on white, which fails AA at this size, so small
   text uses --ink-2 (5.2:1). --ink-3 is reserved for decorative marks. */
.fine{
  font-size:var(--t-cap);
  line-height:1.5;
  color:var(--ink-2);
  letter-spacing:0;
}
.muted{ color:var(--ink-2) }

/* Inline links inside prose */
.prose a,.fine a,#support a{
  color:var(--accent);
  text-underline-offset:.18em;
  text-decoration-thickness:from-font;
}


/* ── 4. Layout primitives ──────────────────────────────────────────────────
   .wrap is defined once, in shell.css, and is what keeps the nav, the page
   body and the footer on the same measure. */
.section{ padding-block:var(--s-5) }
.section--tight{ padding-block:var(--s-4) }

/* Full-bleed band with its own surface. */
.band{ background:var(--paper-2) }

/* The single inverted band. Re-themes the token values *within its own
   subtree only* so every component inside inherits correct contrast —
   the :root definitions are untouched. */
.band--dark{
  background:var(--band);
  --paper:var(--band);
  --paper-2:#111114;
  --card:#141416;
  --ink:#F5F5F7;
  --ink-2:#A1A1A6;
  --ink-3:#8B8B90;
  --hair:rgba(255,255,255,.14);
  --accent:#A99BF5;
  color:var(--ink);
}

.stack > * + *{ margin-top:var(--s-2) }
.rule{ height:1px; background:var(--hair); border:0 }


/* ── 5. Motion ─────────────────────────────────────────────────────────── */
/* Base state is the FINAL state, always. The hidden state only exists once
   site.js has confirmed both JS and prefers-reduced-motion:no-preference by
   putting .js on <html> — so no-JS and reduced-motion users see everything. */

@media (prefers-reduced-motion:no-preference){
  html.js [data-reveal]{
    opacity:0;
    translate:0 1.75rem;
    transition:opacity .7s var(--ease-out), translate .9s var(--ease-out);
    transition-delay:calc(var(--i,0) * 80ms);
  }
  html.js [data-reveal].is-in{ opacity:1; translate:0 0 }

  /* Elements already on screen at load are marked .is-in during priming,
     with transitions suppressed, so they are simply *there* on first paint. */
  html.priming [data-reveal]{ transition:none!important }
}

/* Pinned chapter --------------------------------------------------------
   .pin       = the tall track. Its height minus one viewport is the pin time.
   .pin__view = the sticky child, exactly one viewport tall (+1px seam fix).
   Both are inert unless html.js is present, so the chapter degrades to an
   ordinary stacked module with no JS and for reduced motion.             */
.pin{ position:relative }
.pin__view{ padding-block:var(--s-4) }

@media (prefers-reduced-motion:no-preference){
  @media (min-width:56rem){
    html.js .pin{ height:280svh }
    html.js .pin__view{
      position:sticky;
      top:var(--bar-h);
      height:calc(100svh - var(--bar-h) + 1px);
      display:grid; align-content:center;
      padding-block:0;
      overflow:clip;               /* clip, not hidden — keeps sticky alive */
    }
    html.js .beat{
      opacity:.26;
      transition:opacity .55s var(--ease-quint), translate .55s var(--ease-quint);
      translate:0 0;
    }
    html.js .beat.is-on{ opacity:1 }
  }
}

/* Zero-height scroll marks distributed down the track. */
.pin__marks{ position:absolute; inset:0; pointer-events:none }
.pin__marks span{ position:absolute; left:0; width:1px; height:1px }
.pin__marks span:nth-child(1){ top:22% }
.pin__marks span:nth-child(2){ top:52% }
.pin__marks span:nth-child(3){ top:82% }

/* Inside the pinned frame the module must fit one viewport exactly: kill its
   vertical rhythm padding and size the device by height, not width. */
@media (prefers-reduced-motion:no-preference){
  @media (min-width:56rem){
    html.js .pin__view .module{ padding-block:0 }
    html.js .pin__view .phone{ height:min(600px, 62svh); width:auto }
  }
  /* Short viewports (landscape phones, small laptops) can't hold a pinned
     frame without clipping. Fall back to the stacked module. Checked at
     1024×768 (pin holds: 709px frame, ~600px of content) and at 1024×700
     (falls back). */
  @media (max-height:46rem){
    html.js .pin{ height:auto }
    html.js .pin__view{
      position:static; height:auto;
      padding-block:var(--s-4); overflow:visible;
    }
    html.js .pin__view .phone{ height:auto; width:min(272px,64vw) }
    html.js .beat{ opacity:1 }
  }
}


/* ── 7. App Store badge ────────────────────────────────────────────────────
   COMPLIANCE, do not "improve":
     · self-hosted artwork, height 40px minimum, width auto (localised
       badges have different intrinsic widths — never hardcode width)
     · the grey keyline is part of the artwork; do not restyle it
     · the badge is NEVER transformed, scaled, tilted, recoloured or
       filtered. Hover feedback lives on the wrapper's box-shadow only.
     · the 12px wrapper padding is Apple's mandated clear space
       (>= 1/4 of badge height = 10px at 40px). Keep it empty.
     · exactly ONE badge per page. Secondary CTAs use .pill, not a badge. */
.badge-link{
  display:inline-block;
  padding:12px;
  margin:-12px;                 /* keeps the clear space optically flush */
  border-radius:var(--radius-sm);
  transition:box-shadow var(--dur-fast) linear;
}
@media (hover:hover){
  .badge-link:hover{ box-shadow:0 10px 34px rgba(0,0,0,.20) }
}
.badge-link img{
  height:40px; width:auto;
  transform:none!important; scale:none!important; rotate:none!important;
  filter:none!important;
}


/* ── 8. Hero ───────────────────────────────────────────────────────────── */
.hero{
  position:relative;
  /* The sticky nav is a normal-flow element, so it already occupies --bar-h
     above this box. A plain 100svh here made the hero one bar taller than the
     viewport — the fold cut it on every screen — and the old
     calc(--bar-h + --s-4) top padding reserved that same bar a second time,
     wasting ~60px above the eyebrow. Subtract it once, here. */
  min-height:calc(100svh - var(--bar-h));  /* svh, never vh */
  display:grid; align-content:center;
  padding-block:var(--s-4) var(--s-5);
  padding-bottom:calc(var(--s-5) + env(safe-area-inset-bottom));
  isolation:isolate;
  overflow:clip;
}
/* Ambient Aurora wash. Decorative, never intercepts a click.
   The glow used to start at full strength on the hero's top edge, which
   overflow:clip cut into a visible horizontal seam directly under the nav.
   It now begins at the edge and is masked in, so the colour arrives from
   nothing and leaves to nothing at both ends. */
.hero__glow{
  position:absolute; inset:0 -10% auto; height:76svh; z-index:-1;
  pointer-events:none; opacity:.34;
  background:
    radial-gradient(48% 46% at 22% 26%, var(--cobalt), transparent 68%),
    radial-gradient(46% 44% at 62% 16%, var(--violet), transparent 70%),
    radial-gradient(42% 42% at 92% 36%, var(--mint), transparent 70%);
  filter:blur(60px);
  -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 24%, #000 68%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0, #000 24%, #000 68%, transparent 100%);
}
@media (prefers-color-scheme:dark){ .hero__glow{ opacity:.46 } }

.hero__inner{ max-width:min(100%, 52rem) }
.hero h1{ margin-bottom:var(--s-2); max-width:20ch }
.hero .lead{ max-width:46ch }
.hero__cta{ margin-top:var(--s-3) }
.hero__fine{ margin-top:var(--s-3); max-width:44ch }

.hero__scroll{
  margin-top:var(--s-4);
  display:inline-flex; align-items:center; gap:.5rem;
  font-size:var(--t-cap); color:var(--ink-2);
  text-decoration:none; min-height:44px;
}
.hero__scroll svg{ width:14px; height:14px }
@media (prefers-reduced-motion:no-preference){
  .hero__scroll svg{ animation:nudge 2.2s var(--ease) infinite }
  @keyframes nudge{ 0%,60%,100%{ translate:0 0 } 30%{ translate:0 3px } }
}

/* A landscape phone is ~360px tall, and a 67px headline eats a third of it.
   On short viewports the hero stops reserving a screen and drops a step down
   the type scale, which puts the App Store badge back above the fold at
   740x360 (measured: badge bottom ~260px). */
@media (max-height:34rem){
  .hero{
    min-height:0;
    padding-block:var(--s-2) var(--s-4);
    padding-bottom:calc(var(--s-4) + env(safe-area-inset-bottom));
  }
  .hero h1{ font-size:clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem) }
  .hero .lead{ font-size:var(--t-body); max-width:56ch }
  .hero__cta{ margin-top:var(--s-2) }
  .hero__fine{ margin-top:var(--s-2) }
  .hero__scroll{ margin-top:var(--s-2) }
  .hero__glow{ height:100% }
}


/* ── 9. App sections & product modules ─────────────────────────────────────
   MULTI-APP PATTERN — this is the part built to be duplicated.

   <section class="app" id="<slug>">
     <div class="app__intro">   … eyebrow + name + one-line pitch …
     <div class="module">…</div>          one idea + one screenshot
     <div class="module module--rev">…</div>   media on the other side
   </section>

   Nothing below is NativeScan-specific: no colour, copy or image path is
   baked into a class. See the "ADD APP #2" comment block in index.html.   */

.app{ position:relative }

.app__intro{ padding-block:var(--s-4) var(--s-3) }
.app__intro h2{ max-width:16ch }
.app__intro .lead{ max-width:44ch }

.module{
  display:grid;
  gap:var(--s-3);
  align-items:center;
  padding-block:var(--s-4);
}
.module__copy{ max-width:32rem }
.module__copy :is(h2,h3){ margin-bottom:var(--s-2) }
.module__copy .lead{ max-width:44ch }
.module__note{
  margin-top:var(--s-2);
  padding:var(--s-2);
  border:1px solid var(--hair);
  border-radius:var(--radius-sm);
  background:var(--card);
}

@media (min-width:56rem){
  .module{
    grid-template-columns:1fr 1fr;
    gap:clamp(2.5rem,6vw,6rem);
    padding-block:var(--s-5);
  }
  /* Alternating side. Source order stays copy-then-media for screen readers. */
  .module--rev .module__media{ order:-1 }
}

/* Device frame. Fixed aspect ratio = zero CLS without touching the <img>. */
.phone{
  position:relative;
  width:min(272px, 64vw);
  aspect-ratio:1179/2556;
  margin-inline:auto;
  padding:8px;
  border-radius:clamp(30px,4vw,44px);
  background:linear-gradient(158deg,#3A3A42,#111114 62%);
  box-shadow:
    0 44px 84px -26px rgba(0,0,0,.42),
    0 6px 18px rgba(0,0,0,.10),
    inset 0 0 0 1px rgba(255,255,255,.12);
}
.phone img{
  width:100%; height:100%;
  object-fit:cover;
  border-radius:clamp(22px,3.2vw,36px);
}
.phone::after{                      /* Dynamic Island */
  content:""; position:absolute; top:20px; left:50%;
  translate:-50% 0;
  width:72px; height:20px; border-radius:999px;
  background:#08080A;
}
.band--dark .phone{
  box-shadow:0 44px 90px -22px rgba(0,0,0,.75), inset 0 0 0 1px rgba(255,255,255,.16);
}

/* Beat list inside the pinned chapter */
.beats{ display:grid; gap:var(--s-3); max-width:32rem }
.beat h3{ margin-bottom:.35rem }
.beat p{ color:var(--ink-2) }
.beat__tag{
  display:inline-block; margin-left:.5rem; vertical-align:.18em;
  font-size:.6875rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  padding:.15rem .45rem; border-radius:999px;
  border:1px solid var(--hair); color:var(--ink-2);
}


/* ── 10. Plans ─────────────────────────────────────────────────────────── */
.plans{
  display:grid; gap:var(--s-2);
  margin-top:var(--s-3);
}
@media (min-width:48rem){
  .plans{ grid-template-columns:1fr 1fr; gap:var(--s-3) }
}
.plan{
  position:relative; overflow:hidden;
  background:var(--card);
  border:1px solid var(--hair);
  border-radius:var(--radius);
  padding:var(--s-3);
  box-shadow:var(--shadow);
}
.plan--pro::before{
  content:""; position:absolute; inset:0 0 auto; height:3px;
  background:var(--aurora);
}
.plan h3{ margin-bottom:.25rem }
.plan__kicker{ color:var(--ink-2); font-size:var(--t-cap); margin-bottom:var(--s-2) }
.plan ul{ display:grid; gap:.6rem }
.plan li{
  position:relative; padding-left:1.6rem;
  color:var(--ink-2); font-size:1rem; line-height:1.45;
}
.plan li::before{
  content:""; position:absolute; left:0; top:.5em;
  width:8px; height:8px; border-radius:50%;
  background:linear-gradient(135deg,var(--cobalt),var(--violet));
}
.plan--free li::before{ background:var(--ink-3) }
.plans__fine{ margin-top:var(--s-2); max-width:76ch }


/* ── 11. Mid CTA ───────────────────────────────────────────────────────── */
.cta{ text-align:center }
.cta h2{ max-width:18ch; margin-inline:auto }
.cta .lead{ max-width:44ch; margin:var(--s-2) auto 0 }
.cta__actions{
  margin-top:var(--s-3);
  display:flex; flex-wrap:wrap; gap:var(--s-1);
  justify-content:center;
}


/* ── 12. Studio app rail ───────────────────────────────────────────────── */
.apps{ display:grid; gap:var(--s-2); margin-top:var(--s-3) }
@media (min-width:48rem){ .apps{ grid-template-columns:1fr 1fr } }

.app-card{
  display:grid; gap:.35rem;
  padding:var(--s-3);
  border:1px solid var(--hair);
  border-radius:var(--radius);
  background:var(--card);
  text-decoration:none;
}
.app-card h3{ font-size:var(--t-h3) }
.app-card p{ color:var(--ink-2); font-size:1rem; max-width:46ch }
.app-card .status{
  justify-self:start;
  font-size:.6875rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-2);
  padding:.2rem .5rem; border:1px solid var(--hair); border-radius:999px;
  margin-bottom:.35rem;
}
a.app-card{ transition:box-shadow var(--dur-fast) linear, border-color var(--dur-fast) linear }
@media (hover:hover){
  a.app-card:hover{ border-color:color-mix(in srgb, var(--accent) 45%, var(--hair)); box-shadow:var(--shadow) }
}
.app-card--soon{ opacity:.72 }


/* ── 13. Support / FAQ ─────────────────────────────────────────────────────
   #support is legacy markup preserved byte-for-byte (Apple's App Store
   Support URL points at it). It may only ever be restyled from here —
   never re-authored.                                                      */
#support{
  display:block;
  /* The cards have no measure of their own; at 1440px a card paragraph would
     otherwise run to ~130 characters. Cap the whole column instead. */
  max-width:74ch;
}
#support h2{
  font-size:var(--t-h3);
  margin-top:var(--s-4);
  margin-bottom:var(--s-2);
}
#support h2:first-child{ margin-top:0 }
#support .card{
  border:1px solid var(--hair);
  border-radius:var(--radius-sm);
  background:var(--card);
  padding:var(--s-2);
  margin-bottom:var(--s-1);
}
#support .card h3{
  font-size:1.0625rem; letter-spacing:-.012em;
  margin-bottom:.4rem;
}
#support .card p{ color:var(--ink-2); font-size:1rem }
#support .card p + p{ margin-top:.6rem }
#support .card ul{ margin:.6rem 0 0; display:grid; gap:.45rem }
#support .card li{
  position:relative; padding-left:1.1rem;
  color:var(--ink-2); font-size:1rem;
}
#support .card li::before{
  content:""; position:absolute; left:0; top:.6em;
  width:5px; height:5px; border-radius:50%; background:var(--ink-3);
}
#support .contact-box{
  margin-top:var(--s-3);
  padding:var(--s-3);
  border:1px solid var(--hair);
  border-radius:var(--radius);
  background:var(--paper-2);
  text-align:center;
}
#support .contact-box h2{ margin:0 0 .5rem }
#support .contact-box a{ font-weight:600 }
/* The legacy markup carries one hardcoded ink colour inline, which would be
   unreadable in dark mode. Overridden here rather than by editing it. */
#support .contact-box p[style]{ color:var(--ink-2)!important }


/* ── 14. About ─────────────────────────────────────────────────────────── */
.about{ display:grid; gap:var(--s-3); align-items:center }
@media (min-width:56rem){
  .about{ grid-template-columns:minmax(0,240px) 1fr; gap:clamp(2.5rem,6vw,5rem) }
}
.about__mark img{ width:min(200px,52vw); height:auto }
.about__copy p{ color:var(--ink-2); max-width:56ch }
.about__copy p + p{ margin-top:var(--s-2) }
.about__tagline{
  font-size:var(--t-h3);
  letter-spacing:-.014em;
  color:var(--ink)!important;
  margin-bottom:var(--s-2);
}

/* ── Hero art ────────────────────────────────────────────────────────────
   At 1440 the hero was text-left / empty-right — it read as unfinished.
   A single product shot fills the counterweight and puts the app on screen
   in the first paint. Desktop only: on narrow screens the one-column hero
   is already balanced, and the phone would push the badge below the fold. */
.hero__grid{ display:grid; gap:var(--s-4); align-items:center }
.hero__art{ display:none }

@media (min-width:64rem){
  .hero__grid{ grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr) }
  .hero__art{
    display:block; justify-self:center;
    width:min(300px, 26vw);
    filter:drop-shadow(0 30px 60px rgba(0,0,0,.18));
  }
  .hero__art img{
    display:block; width:100%; height:auto;
    border-radius:34px;
  }
  /* keep the measure tight so the two columns read as a pair */
  .hero__inner .lead{ max-width:30ch }
}
@media (min-width:64rem) and (max-height:44rem){
  /* short laptop / landscape: art would force the badge under the fold */
  .hero__art{ display:none }
  .hero__grid{ grid-template-columns:1fr }
}
@media (prefers-reduced-motion: no-preference) and (min-width:64rem){
  .hero__art{ animation:heroArtIn 1s var(--ease-out) both .15s }
  @keyframes heroArtIn{ from{opacity:0; transform:translateY(18px)} to{opacity:1; transform:none} }
}

/* ── Support FAQ accordion ───────────────────────────────────────────────
   The App Store Support URL points at this section, so every word has to
   stay in the DOM. Collapsing it keeps the content addressable while cutting
   ~5,000px of wall-of-text off the homepage. <details> is used rather than
   JS so it still works with scripting off, and browsers auto-expand a closed
   <details> when the user runs find-in-page. */
.faq{
  border-bottom:1px solid var(--hair);
}
.faq summary{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s-2);
  padding:var(--s-2) 0;
  min-height:44px;                       /* tap target */
  font-size:var(--t-body); font-weight:600; color:var(--ink);
  cursor:pointer; list-style:none;
}
.faq summary::-webkit-details-marker{ display:none }
.faq summary::after{
  content:""; flex:0 0 auto; width:10px; height:10px;
  border-right:2px solid var(--ink-2); border-bottom:2px solid var(--ink-2);
  transform:rotate(45deg); transform-origin:60% 60%;
}
.faq[open] summary::after{ transform:rotate(-135deg) }
.faq summary:hover{ color:var(--accent) }
.faq summary:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:4px }
.faq__body{ padding-bottom:var(--s-3); max-width:74ch; color:var(--ink-2) }
.faq__body :is(p,li){ font-size:var(--t-body); line-height:1.65 }
.faq__body > :first-child{ margin-top:0 }
@media (prefers-reduced-motion: no-preference){
  .faq summary::after{ transition:transform .25s var(--ease) }
}

/* ── Device frame sizing per context ─────────────────────────────────────
   Every screenshot on this page sits in .phone. Two reasons: a bare <img>
   with width/height attributes was being laid out at its literal 1171px
   height and squeezed to the column width (0.299 rendered vs 0.461 natural
   — a 35% horizontal squash on a 390px viewport), and a raw screenshot with
   no bezel reads as a flat asset rather than a phone.

   .phone owns aspect-ratio:1179/2556, which is within 0.04% of the
   screenshots' own 540x1171, so object-fit:cover crops nothing visible. */
.module__media .phone{
  /* 62vw, not 74. At 74 the device filled the column edge-to-edge and read as
     an oversized asset rather than a phone sitting in a layout; 62 leaves it
     obviously object-like with air either side. Capped so it never outgrows
     the desktop size either. */
  width:min(240px, 62vw);
}
@media (min-width:48rem){
  .module__media .phone{ width:min(268px, 34vw) }
}
@media (min-width:64rem){
  .module__media .phone{ width:min(300px, 24vw) }
}
.hero__art .phone{ width:100% }

/* The Dynamic Island was fixed at 72x20 / top:20px, which only looked right
   at exactly 272px wide. Proportional units keep it correct at every size. */
.phone::after{
  top:2.1%;
  width:26.5%;
  height:2.35%;
  min-height:9px;
}
