/* css/home-mobile.css
   ────────────────────────────────────────────────────────────────────────────
   The mobile front page of airmango.com. Linked only from index.html, so every
   rule in here is page-scoped by virtue of where it loads.

   What this is: the CEO's three-screen mobile design (walkthrough video,
   2026-08-24). Landing on airmango.com from a phone gives a horizontal deck of
   three full-height slides — the pitch, the trip, the gigs — and an "Apply as
   a creator" button that fades in once you have read past the first slide. The
   desktop showcase is hidden rather than reflowed: he was explicit that the
   desktop page "doesn't fit for mobile at all", so it is a different page, not
   a narrower one.

   Two deliberate departures from his Figma prototype:

   1. The phone in the mockup shows REAL app screenshots
      (assets/images/phone-screen-hero.png = the feed,
       phone-screen-trip.jpg = the trip behind the clip), not the hand-drawn
      SVG landscape the prototype used. "This is just some AI bullshit here, we
      know what screen that is." phone-screen-hero.png is a JPEG carrying a
      .png name — harmless (browsers sniff the bytes) and left alone because
      the desktop page references the same path.

      The trip shot is the one that goes stale: it is the app's trip screen,
      which is still being redesigned. It is re-shot rather than redrawn —
      /trip.html?id=<published app_trips.id> runs the SAME renderer as the app
      and the creator's phone preview, so a 393x852 capture of it IS the
      current screen. See the comment on that <img> in index.html.

   2. Type and colour follow BRAND.md, not the prototype. The prototype ships
      Plus Jakarta Sans + JetBrains Mono and #ec1358; the brand is Poppins +
      Inter and #E8366D. Fonts are already loaded by css/app-index.css.

   The header is NOT rebuilt here. js/site-header.js already renders a mobile
   topbar of exactly this shape — wordmark left, burger right, working drawer —
   so it is only recoloured for a dark page. The breakpoint below matches that
   file's own 720px switch on purpose; if one moves, both move.
   ──────────────────────────────────────────────────────────────────────────── */

/* Desktop never sees the mobile page. Stated once, unconditionally, so a
   failure to match the media query below leaves it hidden rather than dumped
   at the bottom of the desktop layout. */
.m-front { display: none; }

@media (max-width: 720px) {

  /* ── the page becomes a fixed-height, non-scrolling shell ──────────────── */

  html { height: 100%; }

  body {
    height: 100vh;
    height: 100dvh;
    margin: 0;
    overflow: hidden;
    background: #07080a;
    color: #fff;
  }

  /* The desktop front page and the site footer are not reflowed, they are stood
     down — the mobile page carries its own ending (the CTA).

     Both selectors are needed. js/site-footer.js mounts with
     `ph.outerHTML = HTML`, which REPLACES the #airmango-footer placeholder, so
     that id stops existing the moment the script runs and a rule hung on it
     silently stops matching. footer.footer is the element that actually lands;
     #airmango-footer only covers the gap before the script fires. */
  body > .master-showcase-section,
  body > #airmango-footer,
  body > footer.footer { display: none !important; }

  /* The shared topbar, recoloured for a dark page and floated over the deck:
     its white fill would otherwise cut the sky in half, and the slides already
     reserve top padding for it. */
  .am-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: transparent;
    border-bottom: 0;
    padding: 16px 24px 2px;
  }
  .am-topbar-logo { color: #fff; }
  .am-menu-btn { color: #fff; }

  /* Pinned to the viewport rather than sized as a flex item, so nothing another
     script appends to <body> can squeeze it. That is not hypothetical: the site
     footer above did exactly that, and the staging env banner, toasts and the
     apply modal all mount the same way. */
  .m-front {
    position: fixed;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    isolation: isolate;
  }

  /* ── backdrop: sky, low sun, three ridgelines ──────────────────────────── */

  .m-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

  .m-sky {
    position: absolute;
    inset: 0;
    background: linear-gradient(178deg, #b3bfc6 0%, #9dabb4 12%, #7e8d97 26%,
      #5b6872 40%, #3a444d 54%, #1e252b 70%, #0d1013 86%, #07080a 100%);
  }

  .m-sun {
    position: absolute;
    left: 50%;
    top: 26%;
    transform: translate(-50%, -50%);
    width: 300px;
    height: 190px;
    background: radial-gradient(ellipse at center, rgba(255,231,200,.28) 0%,
      rgba(255,214,170,.09) 45%, rgba(255,214,170,0) 72%);
  }

  .m-range { position: absolute; left: 0; width: 100%; }
  .m-range svg { display: block; width: 100%; height: 100%; }
  .m-r1 { top: 29%; height: 30%; opacity: .2; }
  .m-r2 { top: 40%; height: 32%; opacity: .32; }
  .m-r3 { top: 53%; height: 36%; opacity: .58; }

  /* Sinks the ridgelines into the page floor so the deck text always has a
     dark ground under it, whatever the slide. */
  .m-fade {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(7,8,10,0) 40%, rgba(7,8,10,.62) 68%,
      rgba(7,8,10,.96) 88%, #07080a 100%);
  }

  /* Driven from js/home-mobile.js — the daylight drains as you swipe toward
     the gigs, which are a dark-ground surface. */
  .m-dim { position: absolute; inset: 0; background: #07080a; opacity: 0; }

  /* ── the deck ──────────────────────────────────────────────────────────── */

  .m-deck {
    position: relative;
    z-index: 2;
    flex: 1;
    min-height: 0;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .m-deck::-webkit-scrollbar { display: none; }

  /* js/home-mobile.js hangs this on the deck for the length of a gesture. A
     mandatory snap and a scrollLeft written frame by frame fight each other —
     the snap keeps yanking the deck back to the nearest slide, so a drag that
     should follow the thumb stutters. The class is taken off again once the
     settling scroll has come to rest, which is a snap point anyway. */
  .m-deck--free { scroll-snap-type: none; }

  .m-slide {
    min-width: 100%;
    scroll-snap-align: start;
    /* One flick, one slide. Without this, a hard native swipe hands the deck
       to momentum scrolling, which is free to fly past as many snap points as
       it has speed for — slide 1 straight to slide 3, the middle one never
       seen. `always` makes every slide a stop the fling has to honour, so how
       hard you throw it stops mattering. (The JS gesture in
       js/home-mobile.js:drive() holds the same line for the drag it drives
       itself, where snapping is switched off.) */
    scroll-snap-stop: always;
    display: flex;
    flex-direction: column;
    min-height: 0;
    /* Vertical drags on these two slides are the deck's, not the browser's:
       the page underneath cannot scroll anyway, and claiming the axis up front
       is what keeps the handover to a horizontal swipe instant. */
    touch-action: pan-x;
    /* Clears the fixed topbar (38px tall) and then some — at 46px the headline
       sat right under the wordmark and the two read as one block. */
    padding: 58px 24px 0;
  }

  /* ── type ──────────────────────────────────────────────────────────────── */

  .m-h1 {
    font-family: 'Poppins', sans-serif;
    font-size: 30px;
    line-height: 1.06;
    letter-spacing: -1.1px;
    font-weight: 700;
    margin: 0;
    color: #fff;
    text-shadow: 0 2px 18px rgba(0,0,0,.35);
  }
  .m-h1 b { color: var(--accent, #E8366D); font-weight: 700; }

  /* The gigs headline is a sentence, not a two-line slogan: a notch smaller so
     it does not swallow the slide, and balanced so no word is left on its own. */
  .m-h1-long {
    font-size: 28px;
    letter-spacing: -1px;
    text-wrap: balance;
  }

  .m-lede {
    font-family: 'Inter', sans-serif;
    font-size: 15px;
    line-height: 1.5;
    letter-spacing: -.1px;
    margin: 14px 0 0;
    color: rgba(255,255,255,.72);
    text-shadow: 0 1px 12px rgba(0,0,0,.35);
  }
  .m-lede b { font-weight: 600; color: #fff; }

  /* ── the phone, and the real screens inside it ─────────────────────────── */

  .m-stage {
    position: relative;
    flex: 1;
    min-height: 200px;
    margin-top: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .m-device {
    /* content-box, and the height stated net of the bezel, on purpose.

       aspect-ratio applies to whichever box box-sizing names, and the whole
       page inherits border-box. So under border-box this ratio described the
       OUTER frame, and .m-screen — the frame minus 5px of bezel on every side
       — came out at a different ratio from phone-screen-hero.png (427x924).
       object-fit: cover then quietly cropped 5.4px off the screenshot's width,
       which slid the Trip thumbnail ~2px right of where percentages say it is
       and left the pulse ring below hanging off its left edge.

       content-box makes the ratio describe .m-screen itself, so the screenshot
       fills it with no crop at all and every percentage measured off the file
       lands exactly. The 10px of calc/max-height is that bezel added back: the
       frame is still 100% of the stage, still capped at 440px tall. */
    box-sizing: content-box;
    height: calc(100% - 10px);
    max-height: 430px;
    aspect-ratio: 427 / 924;
    background: #0a0d10;
    border-radius: 32px;
    padding: 5px;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.18), 0 26px 54px rgba(0,0,0,.6);
  }

  .m-screen {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 27px;
    overflow: hidden;
    background: #10161b;
  }

  .m-shot {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Glass, not content — sells the mockup as a device rather than a flat crop. */
  .m-glare {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(118deg, rgba(255,255,255,.09) 0%,
      rgba(255,255,255,.02) 30%, rgba(255,255,255,0) 52%);
  }

  /* ── the Trip button: "if it should have some type of attention around this" ──
     A transparent hit target sat exactly over the Trip thumbnail in the real
     screenshot, carrying the pink pulse ring. Centre and size are measured off
     phone-screen-hero.png by edge-scanning the file: the thumbnail's box is
     x 373-407, y 759-796 of 427x924, so its centre is (390/427, 778/924) and it
     is ~34px across. Percentages land exactly because .m-screen now carries the
     file's aspect ratio uncropped — see the note on .m-device. */
  .m-trip {
    position: absolute;
    left: 91.33%;
    top: 84.2%;
    transform: translate(-50%, -50%);
    /* Wider than the ring on purpose: on the biggest phone the screen is
       ~199px across, so this is a ~36px tap target over a 15px thumbnail. */
    width: 18%;
    aspect-ratio: 1;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  .m-trip::before {
    content: "";
    position: absolute;
    /* The thumbnail is 8.2% of the screen width (35 of 427); 26% inset on an
       18% box puts the ring at 8.64% — flush around it — so the resting state
       never covers the artwork and the growth reads as coming off the button. */
    inset: 26%;
    border-radius: 30%;
    box-shadow: 0 0 0 2px var(--accent, #E8366D);
    animation: m-pulse 2.4s ease-out infinite;
  }

  @keyframes m-pulse {
    0%   { transform: scale(.86); opacity: .9; }
    70%  { transform: scale(1.6); opacity: 0; }
    100% { opacity: 0; }
  }

  .m-trip:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 8px; }

  /* ── slide 3: the gigs ─────────────────────────────────────────────────── */

  /* Taller content than the other two slides on a short phone, so this one is
     allowed to scroll rather than crush the rail. */
  .m-slide-gigs {
    overflow-y: auto;
    overscroll-behavior-y: contain;
    scrollbar-width: none;
    /* The exception to the rule above: this slide has its own vertical scroll
       on a short phone, and it keeps it. The script yields to it and only takes
       the gesture over once the list has run out of room. */
    touch-action: pan-x pan-y;
  }
  .m-slide-gigs::-webkit-scrollbar { display: none; }

  .m-gigwrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }

  /* The headline took the top edge and the rail the bottom, so on a tall phone
     every pixel of slack piled up in one hole between them — one ugly hole in
     the middle of the slide. The text block takes the slack instead and splits
     it 2:1 around itself, so the hero drops well clear of the topbar and the
     gap under it is a third of what it was. */
  .m-gigtext { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .m-gigtext::before { content: ''; flex: 2; }
  .m-gigtext::after  { content: ''; flex: 1; }

  /* Headline sits at the top like the other two slides; the rail is anchored to
     the bottom so the slack collects between them instead of leaving the cards
     floating mid-screen. padding-top is the floor on that gap once a long
     headline has eaten the slack — margin-top:auto alone collapses to nothing. */
  .m-railgroup { padding-top: 22px; }

  .m-railhead {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 12px;
  }
  .m-railhead b {
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -.015em;
    color: #fff;
  }
  .m-railhead em {
    font-style: normal;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 10.5px;
    letter-spacing: .06em;
    color: rgba(255,255,255,.45);
  }

  .m-gigslot { padding-bottom: 24px; }

  /* js/home-mobile.js moves the one real .gigs block in from the desktop
     column — the gig content has a single home in index.html, so the day it
     starts reading from Supabase there is nothing here to keep in step.
     What is left to do is recolour it: those cards are a light-theme
     component landing on a near-black slide. */
  .m-gigslot .gigs { margin-top: 0; }
  .m-gigslot .gigs-head { display: none; }
  .m-gigslot .gigs-track { gap: 12px; padding-bottom: 4px; }

  /* Wider and taller than the desktop card (178px / 106px image): a thumbnail
     that reads at arm's length, and it lands the rail at ~1.6 cards visible so
     the half-card on the right is the thing that says "swipe". */
  .m-gigslot .gig {
    flex: 0 0 202px;
    background: rgba(255,255,255,.075);
    border-color: rgba(255,255,255,.14);
    border-radius: 13px;
  }
  .m-gigslot .gig-img { height: 126px; }
  .m-gigslot .gig-what { color: #fff; }
  .m-gigslot .gig-who { color: rgba(255,255,255,.5); }
  .m-gigslot .gig-amt { color: #fff; }
  .m-gigslot .gigs-empty h3 { color: #fff; }
  .m-gigslot .gigs-empty p { color: rgba(255,255,255,.6); }

  /* ── footer: progress bars + the CTA ──────────────────────────────────── */

  .m-foot {
    position: relative;
    z-index: 3;
    flex: none;
    padding: 0 24px calc(18px + env(safe-area-inset-bottom));
    background: linear-gradient(180deg, rgba(7,8,10,0) 0%, rgba(7,8,10,.9) 30%, #07080a 60%);
  }

  .m-bars { display: flex; gap: 7px; padding: 14px 0 12px; }
  .m-bar {
    flex: 1;
    height: 4px;
    border-radius: 4px;
    background: rgba(255,255,255,.18);
    border: 0;
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .m-bar span { display: block; height: 100%; width: 0; background: #fff; border-radius: 4px; }

  /* Height is reserved whether or not the button is showing, so the deck does
     not resize under the reader's thumb when it fades in. */
  .m-ctaslot { height: 54px; }

  .m-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-family: 'Inter', sans-serif;
    font-size: 16px;
    font-weight: 600;
    border-radius: 14px;
    border: 0;
    background: var(--accent, #E8366D);
    color: #fff;
    text-decoration: none;
    letter-spacing: -.2px;
    opacity: 0;
    transform: translateY(10px);
    pointer-events: none;
  }
  .m-cta:active { background: var(--accent-hover, #c92d5b); }

  .m-front :focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

  /* Short phones (SE-class, and landscape): give the type back some room by
     letting the phone mockup shrink first. */
  @media (max-height: 700px) {
    .am-topbar { padding: 10px 24px 2px; }
    .m-slide { padding-top: 44px; }
    .m-h1 { font-size: 26px; letter-spacing: -.9px; }
    .m-h1-long { font-size: 24px; }
    .m-lede { font-size: 14px; margin-top: 10px; }
    .m-stage { margin-top: 12px; min-height: 150px; }
    .m-railgroup { padding-top: 18px; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .m-deck { scroll-behavior: auto !important; }
  .m-trip::before { animation: none !important; }
  .m-cta { transition: none !important; }
}
