/* ASai home. Tokens: tokens.css. System: design-systems/home.html. Motion rules: docs/motion-continuity.md.
   Two modes:
   - default (no JS, or home.js failed to start): a calm vertical page, labels as exhibits with a still screenshot;
   - html.is-gallery (set by home.js): one pinned viewport, a horizontal track moves under a phone that never moves. */

@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-long); animation-timing-function: var(--ease); }

html { background: var(--wall); transition: background-color var(--dur-medium) var(--ease); }
body { background: var(--wall); transition: background-color var(--dur-medium) var(--ease); color: var(--ink); font: 400 var(--fs-body)/var(--lh-body) var(--font-ui); overflow-x: clip; }
.display { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: var(--display-weight); line-height: var(--lh-display); letter-spacing: -.01em; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.skip { position: absolute; left: 16px; top: -60px; z-index: 50; background: var(--ink); color: var(--on-cta); padding: 10px 14px; border-radius: var(--r-control); text-decoration: none; }
.skip:focus { top: 12px; }

/* ---------- nav ---------- */
.nav { position: fixed; inset: 0 0 auto; z-index: 30; display: flex; align-items: center; gap: var(--s-5); height: 72px; padding: 0 var(--gutter);
  background: rgba(242, 242, 240, .92); box-shadow: 0 1px 0 var(--line); }
.nav__mark { display: block; height: 24px; color: var(--ink); }
.nav__mark svg { height: 100%; width: auto; display: block; }
.nav__apps { display: flex; gap: var(--s-5); margin-left: auto; font-size: 14px; }
.nav__apps a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); text-decoration: none; transition: color var(--dur-micro) var(--ease); }
.nav__apps a:hover, .nav__apps a[aria-current="true"] { color: var(--ink); }
.lang { display: flex; gap: 2px; border: 1px solid var(--line); border-radius: var(--r-control); padding: 2px; }
.lang button { border: 0; background: none; font: 500 12px var(--font-ui); color: var(--ink-3); min-width: 44px; min-height: 44px; border-radius: 9px;   /* touch target >= 44 (AGENTS.md) */ cursor: pointer;
  transition: background var(--dur-micro) var(--ease), color var(--dur-micro) var(--ease); }
.lang button[aria-pressed="true"] { background: var(--ink); color: var(--on-cta); }
.lang-m { display: none; appearance: none; height: 44px; min-width: 76px; padding: 0 32px 0 14px; border: 1px solid var(--line); border-radius: var(--r-control); font: 500 13px var(--font-ui); color: var(--ink);
  background: var(--passe-partout) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%231C1C1C' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 12px center; }

/* ---------- shared pieces ---------- */
.cta { display: inline-flex; align-items: center; gap: 14px; height: 52px; padding: 0 22px; border-radius: var(--r-control); background: var(--cta); color: var(--on-cta);
  font: 500 15px var(--font-ui); text-decoration: none; transition: background var(--dur-micro) var(--ease), transform var(--dur-micro) var(--ease); }
.cta:hover { background: var(--cta-hover); }
.cta:active { transform: translateY(1px); }
.cta__arr { transition: transform var(--dur-short) var(--ease); }
.cta:hover .cta__arr { transform: translateX(4px); }
.label h2 { font-size: var(--fs-display-l); }
.label__attr { font-size: 14px; color: var(--ink-3); margin: var(--s-2) 0 var(--s-3); }
.label__line { color: var(--ink-2); max-width: 36ch; }
.label .cta { margin-top: var(--s-4); }
.label__stores { display: flex; gap: var(--s-4); margin-top: var(--s-1); font-size: 14px; }   /* links are 44px tall, so little extra margin */
.label__stores a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); text-underline-offset: 3px; }
.grain { position: absolute; inset: 0; pointer-events: none; opacity: var(--grain-opacity); z-index: 20;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* ---------- app worlds (each from its own design system) ---------- */
.world--bill-swiper { background:
  radial-gradient(40% 50% at 15% 20%, rgba(13, 217, 196, .45), transparent 70%),
  radial-gradient(40% 50% at 85% 15%, rgba(153, 51, 242, .42), transparent 70%),
  radial-gradient(40% 50% at 20% 85%, rgba(77, 89, 255, .42), transparent 70%),
  radial-gradient(40% 50% at 85% 85%, rgba(212, 64, 42, .38), transparent 70%),
  radial-gradient(ellipse at center, #241A52, #06061A 65%); }
.world--bill-swiper-warm { background:   /* Bill Swiper "Warm Friendly" (design-systems/bill-swiper-warm.html) */
  radial-gradient(38% 48% at 22% 28%, rgba(255, 207, 92, .55), transparent 70%),
  radial-gradient(40% 50% at 78% 22%, rgba(29, 83, 222, .28), transparent 70%),
  radial-gradient(42% 52% at 30% 82%, rgba(127, 200, 182, .45), transparent 70%),
  radial-gradient(45% 55% at 80% 80%, rgba(255, 122, 26, .50), transparent 70%),
  linear-gradient(180deg, #C4B39E, #DECDB6 50%, #E4D3BD); }   /* tones of media C1 (world-bill-swiper-warm) */
.world--spendr { background:
  radial-gradient(45% 55% at 22% 25%, rgba(76, 157, 240, .30), transparent 70%),
  radial-gradient(35% 45% at 80% 78%, rgba(224, 105, 95, .16), transparent 70%),
  linear-gradient(180deg, #324252, #3A404D 50%, #3A353B); }   /* tones of media D1 (world-spendr), measured by prepare-media */
.world--rent-assistance { background:
  radial-gradient(45% 55% at 30% 30%, rgba(91, 108, 255, .34), transparent 70%),
  radial-gradient(40% 50% at 78% 75%, rgba(79, 142, 247, .20), transparent 70%),
  linear-gradient(180deg, #262E50 0%, #222C45 50%, #192841 100%); }   /* tones of media E1 (world-rent-assistance) */

/* ======================================================================
   DEFAULT MODE — no JS: vertical exhibits, nothing moves
   ====================================================================== */
.gallery { padding-top: 72px; }
.viewport { position: relative; }
.phone, .cue { display: none; }
.track { display: block; }                        /* the hero title lives in the track: keep it, drop the timeline segments */
html:not(.is-gallery) .track .seg:not(.seg--hero) { display: none; }
html:not(.is-gallery) .hero-title { max-width: 900px; margin: 0 auto; padding: var(--s-8) var(--gutter) 0; text-align: center; }
.labels { display: grid; gap: var(--s-8); max-width: var(--maxw); margin: 0 auto; padding: var(--s-8) var(--gutter); }
.labels::before { content: none; }
.label { display: grid; grid-template-columns: 1fr auto; column-gap: var(--s-6); align-items: start; background: var(--passe-partout); padding: var(--s-6); border-radius: var(--r-frame); box-shadow: var(--shadow-frame); }
.label > :not(.label__shot) { grid-column: 1; }
.label__shot.phone { display: block; grid-column: 2; grid-row: 1 / span 6; --phone-w: 200px; }   /* the one shared mockup (AGENTS rule 7) */
.label .cta { justify-self: start; }

/* ======================================================================
   GALLERY MODE — html.is-gallery
   ====================================================================== */
.is-gallery {
  --pw: min(22svh, 56vw);                   /* phone width; the phone never changes size or position */
  --ph: calc(var(--pw) * 2.235);            /* screen 1080:2340 + bezel */
  --phone-cy: 47svh;                        /* phone centre */
  --label-w: min(30vw, 380px);
}
.is-gallery .gallery { padding-top: 0; }     /* height is set by home.js = track travel + one viewport */
.is-gallery .viewport { position: sticky; top: 0; height: 100vh; height: 100lvh; overflow: hidden; }   /* the LARGE viewport: when Safari hides its bars the scene still reaches the bottom edge */
.is-gallery .track { display: flex; position: absolute; inset: 0 auto 0 0; height: 100%; will-change: transform; }

/* timeline: invisible segments whose widths set how long each part lasts */
.is-gallery .seg { position: relative; flex: none; height: 100%; display: block; }
.is-gallery .seg--hero { width: 95vw; }   /* > phone centre + crossfade: no world or label on the first screen */
.is-gallery .seg--in, .is-gallery .seg--out { width: 12vw; }
.is-gallery .seg--world { width: 100vw; }
.is-gallery .seg--light { width: 45vw; }

/* the gallery is the viewport; app worlds are full-bleed layers above it, cross-faded by home.js */
/* fallback under the generated gallery (A1): same wall/floor tones and horizon as the graded image, so it fades in without a jump */
.is-gallery .viewport { background: linear-gradient(180deg, var(--gallery-wall) 0 74.8%, #C9C6C0 75%, var(--gallery-floor) 75.3% 100%); }
@media (orientation: portrait) { .is-gallery .viewport { background: linear-gradient(180deg, var(--gallery-wall-p) 0 69.8%, #CDCAC5 70%, var(--gallery-floor-p) 70.3% 100%); } }
.is-gallery .viewport::before { content: ""; position: absolute; inset: 0; background: var(--light-wash); }
.stage { display: none; }
.is-gallery .stage { display: block; position: absolute; inset: 0; z-index: 2; }
.is-gallery .stage__world { position: absolute; inset: 0; opacity: 0; visibility: hidden; transform: scale(1.04); will-change: opacity, transform; }
.is-gallery .track { z-index: 3; pointer-events: none; }
.is-gallery .hero-title { position: absolute; left: 50vw; transform: translateX(-50%); top: calc(var(--phone-cy) + var(--ph) / 2 + var(--pw) * .28); width: min(92vw, 900px); text-align: center; }
.hero-title h1 { font-size: clamp(38px, 6.2svh, 84px); }
.hero-title h1, .hero-title p { text-wrap: balance; }
.hero-title p { font-size: var(--fs-lead); color: var(--ink-on-gallery); margin-top: var(--s-2); }

/* generated media (docs/prompts/m3-home.md): sits on top of the CSS fallback of the same colour, fades in, never flashes */
.is-gallery .media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--dur-medium) var(--ease); }
.is-gallery .media.is-ready { opacity: 1; }
/* the still is the under-layer; the video (same first frame) plays above it — otherwise the still hides the light */
.is-gallery picture > .media { z-index: 0; }
.is-gallery video.media { z-index: 1; }

/* the phone: fixed in the viewport for the whole story */
.is-gallery .phone { display: block; --phone-w: var(--pw); position: absolute; left: 50%; top: var(--phone-cy); z-index: 5;
  transform: translate(-50%, -50%) translateY(var(--lift, 0px));
  transition: transform var(--dur-short) var(--ease); }
.phone .scr { opacity: 0; transition: opacity var(--dur-medium) var(--ease); }
.phone .scr.is-on { opacity: 1; }
.phone .grey { position: absolute; inset: 0; clip-path: inset(0 0 0 0); }
.phone .scr { will-change: opacity; }   /* every screen is its own layer from the start: no raster cost on first show */

/* the label: one card per app, only the active one is shown */
.is-gallery .labels { display: block; position: absolute; inset: 0; padding: 0; max-width: none; pointer-events: none; z-index: 6; }
.is-gallery .label { position: absolute; left: max(var(--gutter), 5vw); top: 50%; width: var(--label-w); display: block; padding: var(--s-5);
  opacity: 0; transform: translateY(calc(-50% + 12px)); visibility: hidden;
  transition: opacity var(--dur-short) var(--ease), transform var(--dur-short) var(--ease), visibility 0s linear var(--dur-short); }   /* the leaving label goes first… */
.is-gallery .label.is-on { opacity: 1; transform: translateY(-50%); visibility: visible; pointer-events: auto;
  transition: opacity var(--dur-medium) var(--ease) var(--dur-short), transform var(--dur-medium) var(--ease) var(--dur-short), visibility 0s; }   /* …then the next one arrives: never two labels at once */
.is-gallery .label__shot { display: none; }

.is-gallery .cue { display: flex; position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%); align-items: center; gap: 10px; font-size: 13px; color: var(--ink-on-gallery); z-index: 7;
  transition: opacity var(--dur-short) var(--ease); }
.is-gallery .cue i { width: 1px; height: 22px; background: var(--rule); }
.is-gallery .cue.is-off { opacity: 0; }

.foot { display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap; padding: var(--s-6) var(--gutter); border-top: 1px solid var(--line); font-size: 14px; color: var(--ink-3); }
.foot__mark { height: 20px; color: var(--ink); } .foot__mark svg { height: 100%; width: auto; display: block; }
.foot nav { display: flex; flex-wrap: wrap; gap: 0 var(--s-4); margin-right: auto; } .foot a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); }
.foot .foot__legal { margin-right: 0; }

/* ---------- small screens ---------- */
@media (max-width: 1100px) { .nav__apps { display: none; } }
@media (max-width: 760px) {
  .nav { height: 64px; }
  .lang { display: none; }
  .lang-m { display: block; }
  .nav { gap: var(--s-3); }
}
/* phones and portrait tablets: label under the phone (side by side the label would cover the phone at 768-1100 px) */
@media (max-width: 760px), (orientation: portrait) and (max-width: 1100px) {
  .label { grid-template-columns: 1fr; padding: var(--s-4); }
  .label__shot.phone { grid-column: 1; grid-row: auto; margin-top: var(--s-4); --phone-w: min(56vw, 220px); }
  .is-gallery { --pw: min(19svh, 48vw); --phone-cy: 36svh; }
  .is-gallery .label { left: var(--gutter); right: var(--gutter); width: auto; top: auto; bottom: calc(100lvh - 100svh + var(--box-extra, 0px) + max(16px, env(safe-area-inset-bottom)));   /* sits above the bars while they show (the box is 100lvh tall) */ padding: var(--s-4); transform: translateY(12px); }
  .is-gallery .label.is-on { transform: none; }
  .is-fold.is-gallery .label { bottom: var(--label-lift, 16px); }   /* above the browser's bottom bar (home.js) */
  .is-gallery .label h2 { font-size: 40px; }
  .is-gallery .label__attr { margin: 4px 0 8px; }
  .is-gallery .label .cta { margin-top: var(--s-3); }
  .is-gallery .hero-title h1 { font-size: 38px; }
  .is-gallery .hero-title { top: calc(70svh + 18px); }   /* whole title on the floor, below the horizon of A1 9:16 */
}


/* ======================================================================
   FOLD PROTOTYPE (?fold on touch screens): native scroll with snap stops + iPhone-Duo-like fold between worlds
   ====================================================================== */
/* the page itself does not scroll in fold mode: BODY is a full-screen scroller. Safari 26 does not paint fixed/sticky
   layers of the page below its bottom bar; a sticky scene inside an inner scroller is ordinary content and reaches the
   screen edge (home.js sets the body height to the full screen) */
html.is-fold { height: 100%; overflow: hidden; }
html.is-fold body { height: 100lvh; overflow-x: hidden; overflow-y: auto; overscroll-behavior: none; }
html.fold-snap body { scroll-snap-type: y mandatory; }   /* set by home.js after the snap anchors are placed */
.is-fold .gallery { position: relative; }
.is-fold .snap { position: absolute; left: 0; width: 1px; height: 1px; scroll-snap-align: start; scroll-snap-stop: always; pointer-events: none; }
.is-fold .foot { scroll-snap-align: end; }
.is-fold .stage__world { transform-origin: 50% 40%; }
/* pre-blurred copy over the sharp still and the video; stronger towards the edges, lighter near the phone (depth of field) */
.is-fold .media--blur { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 2; opacity: 0; pointer-events: none;
  -webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 40%, rgba(0, 0, 0, .55), #000 75%); mask-image: radial-gradient(ellipse 60% 55% at 50% 40%, rgba(0, 0, 0, .55), #000 75%); }
.is-fold .phone__screen { transform-origin: 50% 50%; will-change: filter, transform; }
.is-fold .label, .is-fold .label.is-on { transition: none; opacity: 1; will-change: transform; }   /* fold: the label is a sheet driven by the scroll, not a timed fade */


/* ---------- menu (burger): apps, legal, write to us ---------- */
.burger { display: none; flex-direction: column; justify-content: center; align-items: center; gap: 6px; width: 44px; height: 44px; margin-left: var(--s-2); flex: none;
  border: 1px solid var(--line); border-radius: var(--r-control); background: var(--passe-partout); color: var(--ink); cursor: pointer; }
.burger i { display: block; width: 18px; height: 1.5px; background: currentColor; }
.menu { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; overflow-y: auto; overscroll-behavior: contain;
  background: var(--passe-partout); color: var(--ink); opacity: 0; transform: translateY(-12px);
  transition: opacity var(--dur-short) var(--ease), transform var(--dur-short) var(--ease), overlay var(--dur-short) allow-discrete, display var(--dur-short) allow-discrete; }
.menu[open] { opacity: 1; transform: none; }
@starting-style { .menu[open] { opacity: 0; transform: translateY(-12px); } }
.menu::backdrop { background: transparent; }
.menu__bar { position: sticky; top: 0; display: flex; align-items: center; justify-content: space-between; height: 72px; padding: 0 var(--gutter); padding-top: env(safe-area-inset-top); box-sizing: content-box; background: var(--passe-partout); box-shadow: 0 1px 0 var(--line); }
.menu__close { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--line); border-radius: var(--r-control); background: none; color: var(--ink); cursor: pointer; }
.menu__body { max-width: 640px; margin: 0 auto; padding: var(--s-5) var(--gutter) calc(var(--s-6) + env(safe-area-inset-bottom)); display: grid; gap: var(--s-5); }
.menu__apps { display: grid; }
.menu__apps a { font-size: var(--fs-display-l); color: var(--ink); text-decoration: none; padding: var(--s-1) 0; transition: color var(--dur-micro) var(--ease); }
.menu__apps a:hover { color: var(--ink-2); }
.menu__legal { display: flex; flex-wrap: wrap; gap: 0 var(--s-4); }
.menu__legal a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); }
.menu__mail { display: grid; gap: var(--s-2); justify-items: start; padding-top: var(--s-4); border-top: 1px solid var(--line); }
.menu__mail h2 { font-size: var(--fs-display-l); margin-bottom: var(--s-2); }
.menu__mail label { font-size: var(--fs-meta); color: var(--ink-3); }
.menu__mail textarea { width: 100%; box-sizing: border-box; min-height: 120px; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--passe-partout);
  font: 400 var(--fs-body)/var(--lh-body) var(--font-ui); color: var(--ink); resize: vertical; }
.menu__mail .cta { margin-top: var(--s-2); border: 0; cursor: pointer; }
.menu__hint { font-size: var(--fs-meta); color: var(--ink-3); }
.menu__hint a { color: var(--ink-2); }
html.menu-open, html.menu-open body { overflow: hidden; }
/* only where the top bar has no app links (owner: desktop already shows every app in the bar) */
@media (max-width: 1100px) { .burger { display: inline-flex; } .nav__contact { margin-left: auto; } }
/* Contact us: everywhere (owner); opens the same sheet with the mail form only */
.nav__contact { display: inline-flex; align-items: center; min-height: 44px; padding: 0; border: 0; background: none; font: 400 14px var(--font-ui); color: var(--ink-2); cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--rule); transition: color var(--dur-micro) var(--ease); }
.nav__contact:hover { color: var(--ink); }
.menu--mail .menu__apps, .menu--mail .menu__legal { display: none; }
.menu--mail .menu__mail { border-top: 0; padding-top: 0; }
@media (max-width: 760px) { .menu__bar { height: 64px; } }
