/* ==========================================================================
   apps.css — the EDC Apps section: /apps/ (the showcase) and one page per app
   at /apps/<name>.html. Added 2026-10-11.

   ONE STYLESHEET FOR EVERY APP
   ----------------------------
   Each app page is the same markup with different words, screenshots and an
   app theme class. Nothing in here is specific to one app except the theme
   blocks at the end (.app-theme-*). A new app = a copy of an existing app page
   plus one new theme block. See docs/apps-section.md.

   TOKENS
   ------
   EDC chrome, read from the existing tree, nothing invented: navy #16213e and
   #0a1930, gold #d4a84b (#9a6b12 where gold text sits on white, 4.68:1), ink
   #1F2937 / #374151, muted #6b7280, border #E5E7EB, cream #FBF7F0, sub-text on
   navy #b0bec5, radii 8/12/16/999, easing cubic-bezier(0.22,1,0.36,1),
   Montserrat for text and Playfair Display for headings.

   App accents are each app's OWN brand colours, sampled from its Google Play
   graphics rather than chosen here:
     ForecastPal  #3b82f6 (headline blue), #1d3fad / #0f172b (store gradient),
                  #bfdbfe (store subtitle)
     Glow Merge   #0c0f2b / #34263b (feature-graphic sky), #ffd79a (tagline)

   CONTRAST (measured, WCAG 2.x)
     #3b82f6 on white 3.68 → used for large text, icons and fills only
     #1d3fad on white 8.87 → the small-text form of the ForecastPal accent
     #bfdbfe on #1d3fad 6.24, #d4a84b on #0a1930 7.95, #b0bec5 on #0a1930 9.22

   MOTION
   ------
   Entrance reveals fire once via IntersectionObserver in assets/js/apps.js and
   are gated by html.app-js, so with JS off everything is simply there.
   assets/css/motion-guard.css is linked after this file on every page and
   already collapses all motion under prefers-reduced-motion; the block at the
   end of this file additionally pins every reveal to its final state there.

   NO overflow-x:hidden ANYWHERE ABOVE THE NAV, and no backdrop-filter on an
   ancestor of it: both break the shared header's fixed drawer once scrolled.
   Sections that need clipping use overflow: clip on themselves.
   ========================================================================== */

:root {
  --app-navy: #16213e;
  --app-navy-deep: #0a1930;
  --app-gold: #d4a84b;
  --app-gold-ink: #9a6b12;
  --app-gold-soft: rgba(212, 168, 75, 0.12);
  --app-ink: #1F2937;
  --app-body: #374151;
  --app-muted: #6b7280;
  --app-line: #E5E7EB;
  --app-cream: #FBF7F0;
  --app-sub-dark: #b0bec5;
  --app-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --app-r-sm: 8px;
  --app-r-md: 12px;
  --app-r-lg: 16px;
  --app-r-xl: 28px;

  /* Default app accent; each theme block overrides these. */
  --app-accent: var(--app-gold);
  --app-accent-ink: var(--app-gold-ink);
  --app-accent-light: #E1B168;
  --app-sky-1: var(--app-navy-deep);
  --app-sky-2: var(--app-navy);
  --app-glow: rgba(212, 168, 75, 0.35);
}

.app-page { background: #fff; color: var(--app-body); }
/* :where() keeps this at element specificity, so every component's own heading
   colour wins, and it is scoped to <main> so the shared footer's gold
   .footer-title headings are left alone. */
:where(.app-page main) :is(h1, h2, h3) { font-family: 'Playfair Display', Georgia, serif; color: var(--app-ink); }

.app-wrap { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 16px; }
@media (min-width: 768px) { .app-wrap { padding: 0 24px; } }

.app-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.app-skip { position: absolute; left: -10000px; }
.app-skip:focus { position: fixed; left: 16px; top: 16px; z-index: 300; background: var(--app-ink); color: #fff; padding: 0.75rem 1rem; border-radius: var(--app-r-sm); }

.app-page a:focus-visible,
.app-page button:focus-visible,
.app-page summary:focus-visible,
.app-page video:focus-visible {
  outline: 3px solid var(--app-gold);
  outline-offset: 3px;
  border-radius: var(--app-r-sm);
}

/* ---------- Shared bits ---------- */

.app-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 16px; border-radius: 999px;
  background: var(--app-gold-soft); color: var(--app-gold);
  font: 600 0.8rem/1.2 'Montserrat', sans-serif; letter-spacing: 0.12em; text-transform: uppercase;
}
.app-eyebrow-light { background: rgba(255, 255, 255, 0.1); color: #fff; }
.app-eyebrow-ink { background: var(--app-gold-soft); color: #6f4c08; }

.app-h2 { font-size: clamp(1.9rem, 4vw, 2.9rem); line-height: 1.12; font-weight: 700; margin: 14px 0 12px; letter-spacing: -0.01em; }
.app-intro { font-size: 1.08rem; line-height: 1.7; color: var(--app-muted); max-width: 640px; }
.app-section-head { text-align: center; margin: 0 auto 48px; max-width: 720px; }
.app-section-head .app-intro { margin: 0 auto; }

.app-section { padding: 88px 0; }
@media (max-width: 767px) { .app-section { padding: 64px 0; } }

/* The official Google Play badge. The PNG carries Google's own clear space,
   so it is used at its natural ratio, never cropped, recoloured or redrawn. */
.app-badge { display: inline-block; line-height: 0; border-radius: var(--app-r-md); transition: transform 240ms var(--app-ease); }
.app-badge img { width: 200px; height: auto; display: block; }
@media (pointer: fine) { .app-badge:hover { transform: translateY(-2px); } }

.app-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 48px; padding: 12px 22px; border-radius: 999px;
  font: 600 0.98rem/1.2 'Montserrat', sans-serif; text-decoration: none;
  transition: transform 240ms var(--app-ease), background-color 240ms var(--app-ease), box-shadow 240ms var(--app-ease), color 240ms var(--app-ease);
}
.app-btn svg { width: 18px; height: 18px; flex: none; }
.app-btn-gold { background: var(--app-gold); color: var(--app-navy-deep); box-shadow: 0 10px 30px rgba(212, 168, 75, 0.25); }
.app-btn-ghost { background: rgba(255, 255, 255, 0.08); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28); }
.app-btn-line { background: #fff; color: var(--app-ink); box-shadow: inset 0 0 0 1px var(--app-line); }
@media (pointer: fine) {
  .app-btn-gold:hover { transform: translateY(-2px); box-shadow: 0 14px 36px rgba(212, 168, 75, 0.35); }
  .app-btn-ghost:hover { background: rgba(255, 255, 255, 0.16); }
  .app-btn-line:hover { box-shadow: inset 0 0 0 1px var(--app-gold); color: var(--app-gold-ink); }
  .app-btn:hover .app-arrow { transform: translateX(4px); }
}
.app-arrow { transition: transform 240ms var(--app-ease); }

.app-chips { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.app-chips li {
  padding: 6px 12px; border-radius: 999px;
  font: 600 0.8rem/1.2 'Montserrat', sans-serif;
  background: rgba(255, 255, 255, 0.1); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

.app-tag-premium {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  background: var(--app-gold); color: var(--app-navy-deep);
  font: 700 0.68rem/1.2 'Montserrat', sans-serif; letter-spacing: 0.08em; text-transform: uppercase;
  vertical-align: middle;
}

/* ---------- The phone ----------
   A CSS frame around a real screenshot. The screenshots are cropped at the tab
   bar (1236x2390 source), so the screen ratio is fixed here and nothing jumps
   while an image loads. */
.app-phone {
  position: relative;
  width: 100%;
  max-width: 300px;
  padding: 24px 9px 12px;
  border-radius: 44px;
  background: linear-gradient(160deg, #1f2937, #0b0f1a 60%);
  box-shadow:
    0 0 0 1.5px rgba(255, 255, 255, 0.08) inset,
    0 40px 80px -24px rgba(10, 25, 48, 0.55),
    0 16px 32px -16px rgba(10, 25, 48, 0.4);
}
.app-phone::before { /* camera */
  content: ""; position: absolute; top: 9px; left: 50%;
  width: 9px; height: 9px; margin-left: -4.5px; border-radius: 50%;
  background: #000; box-shadow: 0 0 0 1.5px #263043;
}
.app-screen {
  position: relative;
  aspect-ratio: 1236 / 2390;
  border-radius: 30px;
  overflow: hidden;
  background: #0f172b;
}
.app-screen img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }

/* The widget step: the real widget on the app's own sky, not a fake home screen. */
.app-screen-widget {
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(170deg, var(--app-sky-1), var(--app-sky-2));
}
.app-screen-widget img { width: 82%; height: auto; object-fit: contain; border-radius: 22px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35); }

/* ==========================================================================
   APP PAGE — hero
   ========================================================================== */

.app-hero {
  position: relative;
  overflow: clip;
  color: #fff;
  background:
    radial-gradient(900px 520px at 85% 15%, rgba(255, 255, 255, 0.1), transparent 60%),
    linear-gradient(165deg, var(--app-sky-1) 0%, var(--app-sky-1) 35%, var(--app-sky-2) 100%);
  padding: 40px 0 72px;
}
/* Static rain: a still texture, not an animation. */
.app-hero-rain::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(105deg, rgba(255, 255, 255, 0.07) 0 1px, transparent 1px 22px);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 75%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 75%);
}
.app-hero > .app-wrap { position: relative; }

.app-crumbs { font: 500 0.85rem/1.4 'Montserrat', sans-serif; color: var(--app-sub-dark); margin-bottom: 28px; }
.app-crumbs ol { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; }
.app-crumbs li + li::before { content: "›"; margin-right: 6px; opacity: 0.6; }
.app-crumbs a { color: var(--app-sub-dark); text-decoration: none; }
.app-crumbs a:hover { color: #fff; text-decoration: underline; }
.app-crumbs [aria-current] { color: #fff; }

.app-hero-grid { display: grid; gap: 48px; align-items: center; }
@media (min-width: 960px) { .app-hero-grid { grid-template-columns: 1.08fr 0.92fr; gap: 56px; } }

.app-id { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; }
.app-id img { width: 64px; height: 64px; border-radius: 15px; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3); }
.app-id-name { font: 700 1.15rem/1.2 'Montserrat', sans-serif; color: #fff; margin: 0; }
.app-id-meta { font: 500 0.88rem/1.3 'Montserrat', sans-serif; color: var(--app-sub-dark); margin: 2px 0 0; }

.app-hero h1 {
  color: #fff;
  font-size: clamp(2.7rem, 7vw, 4.9rem);
  line-height: 1.02; font-weight: 700; letter-spacing: -0.02em;
  margin: 0 0 20px;
}
.app-hero h1 .app-hl { color: var(--app-accent-light); font-style: italic; }
.app-lead { font-size: clamp(1.05rem, 1.6vw, 1.22rem); line-height: 1.65; color: #e5e7eb; max-width: 560px; margin: 0 0 26px; }

.app-cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 18px; }
.app-fine { font: 500 0.88rem/1.5 'Montserrat', sans-serif; color: var(--app-sub-dark); margin: 14px 0 0; }

.app-qr {
  display: none;
  align-items: center; gap: 16px;
  margin-top: 30px; padding: 14px 18px 14px 14px;
  max-width: 400px;
  border-radius: var(--app-r-lg);
  background: rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
}
.app-qr img { width: 92px; height: 92px; padding: 7px; background: #fff; border-radius: 10px; flex: none; }
.app-qr p { margin: 0; font: 500 0.9rem/1.5 'Montserrat', sans-serif; color: #e5e7eb; }
.app-qr strong { display: block; color: #fff; font-weight: 700; margin-bottom: 2px; }
@media (min-width: 960px) and (pointer: fine) { .app-qr { display: flex; } }

.app-hero-visual { position: relative; display: flex; justify-content: center; padding: 10px 0 0; }
.app-hero-visual .app-phone { max-width: 290px; }
.app-hero-glow {
  position: absolute; width: 420px; height: 420px; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border-radius: 50%; background: radial-gradient(closest-side, var(--app-glow), transparent);
  pointer-events: none;
}

/* Floating cards around the hero phone: exact app text, never invented. */
.app-float {
  position: absolute; z-index: 2;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border-radius: 18px;
  background: rgba(255, 255, 255, 0.96); color: var(--app-ink);
  box-shadow: 0 18px 40px -12px rgba(10, 25, 48, 0.45);
  font-family: 'Montserrat', sans-serif;
}
.app-float img { width: 30px; height: 30px; border-radius: 8px; flex: none; }
.app-float-app { font-size: 0.7rem; font-weight: 600; color: var(--app-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.app-float-title { font-size: 0.9rem; font-weight: 700; line-height: 1.3; }
.app-float-body { font-size: 0.82rem; line-height: 1.35; color: var(--app-body); }
.app-float-notif { top: 0; left: 50%; width: 300px; margin-left: -150px; }
.app-float-pill { bottom: 9%; left: 12px; align-items: center; white-space: nowrap; font-size: 0.85rem; font-weight: 700; padding: 10px 16px; border-radius: 999px; }
.app-float-pill svg { width: 18px; height: 18px; color: #16a34a; flex: none; }
@media (min-width: 600px) {
  .app-float-pill { left: auto; right: 50%; margin-right: 70px; }
}
@media (min-width: 480px) {
  .app-float-notif { left: auto; right: 50%; margin: 0 -90px 0 0; width: 290px; top: 1%; }
}
@media (max-width: 400px) {
  .app-float-notif { width: 270px; margin-left: -135px; }
}

/* ==========================================================================
   APP PAGE — feature tour
   Base layout (JS off, or narrower than 1024px): each feature is a row with
   its own phone. Enhanced (html.app-tour-js at >=1024px): one sticky phone
   whose screen follows the feature in the middle of the viewport.
   ========================================================================== */

.app-tour { background: var(--app-cream); }
.app-tour-grid { position: relative; }
.app-steps { display: grid; gap: 72px; list-style: none; margin: 0; padding: 0; }
.app-step { display: grid; gap: 28px; align-items: center; }
@media (min-width: 768px) {
  .app-step { grid-template-columns: 1fr 1fr; gap: 56px; }
  .app-step:nth-child(even) .app-step-media { order: -1; }
}
.app-step-media { display: flex; justify-content: center; }
.app-step-media .app-phone { max-width: 260px; }

.app-step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 12px;
  background: var(--app-accent-ink); color: #fff;
  font: 700 0.9rem/1 'Montserrat', sans-serif; margin-bottom: 16px;
}
.app-step h3 { font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 1.15; margin: 0 0 12px; }
.app-step p { font-size: 1.04rem; line-height: 1.7; margin: 0 0 14px; }
.app-quote {
  display: inline-block; margin: 4px 0 16px; padding: 10px 16px; border-radius: 14px;
  background: #fff; box-shadow: inset 0 0 0 1px var(--app-line), 0 6px 18px rgba(10, 25, 48, 0.06);
  font: 600 0.98rem/1.45 'Montserrat', sans-serif; color: var(--app-ink);
}
.app-ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.app-ticks li { position: relative; padding-left: 30px; line-height: 1.55; }
.app-ticks li::before {
  content: ""; position: absolute; left: 0; top: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--app-accent-ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.5 10.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat;
}

.app-stage { display: none; }

@media (min-width: 1024px) {
  .app-tour-js .app-tour-grid { display: grid; grid-template-columns: minmax(0, 540px) 340px; justify-content: center; gap: 120px; }
  .app-tour-js .app-steps { gap: 0; }
  .app-tour-js .app-step { display: flex; align-items: center; min-height: 80vh; padding: 6vh 0; }
    .app-tour-js .app-step-media { display: none; }
  .app-tour-js .app-step-text { max-width: 520px; opacity: 0.32; transform: translateY(8px); transition: opacity 500ms var(--app-ease), transform 500ms var(--app-ease); }
  .app-tour-js .app-step.is-active .app-step-text { opacity: 1; transform: none; }

  .app-tour-js .app-stage { display: block; }
  .app-stage-inner { position: sticky; top: calc(50vh - 300px); display: flex; align-items: center; gap: 22px; }
  .app-stage .app-phone { max-width: 300px; flex: none; width: 300px; }
  .app-stage .app-screen > * {
    position: absolute; inset: 0;
    opacity: 0; transform: scale(1.03);
    transition: opacity 600ms var(--app-ease), transform 800ms var(--app-ease);
  }
  .app-stage .app-screen > .is-active { opacity: 1; transform: none; }
  .app-stage-dots { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
  .app-stage-dots li { width: 8px; height: 8px; border-radius: 50%; background: rgba(10, 25, 48, 0.18); transition: background-color 300ms var(--app-ease), transform 300ms var(--app-ease); }
  .app-stage-dots li.is-active { background: var(--app-accent-ink); transform: scale(1.4); }
}

/* ==========================================================================
   APP PAGE — film
   ========================================================================== */

.app-film { background: var(--app-navy-deep); color: #fff; overflow: clip; }
.app-film .app-h2 { color: #fff; }
.app-film .app-intro { color: var(--app-sub-dark); }
.app-film-frame {
  position: relative; max-width: 980px; margin: 0 auto;
  border-radius: var(--app-r-xl); overflow: hidden;
  background: #000; aspect-ratio: 16 / 9;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1), 0 40px 90px -30px var(--app-glow);
}
.app-film-frame video { display: block; width: 100%; height: 100%; object-fit: cover; background: #000; }
.app-film-play {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: flex; align-items: flex-end; justify-content: flex-start;
  border: 0; padding: clamp(12px, 3vw, 28px); cursor: pointer;
  background: linear-gradient(180deg, transparent 55%, rgba(10, 25, 48, 0.55));
}
.app-film-play[hidden] { display: none; }
.app-film-play span {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 24px 14px 16px; border-radius: 999px;
  background: var(--app-gold); color: var(--app-navy-deep);
  font: 700 1rem/1 'Montserrat', sans-serif;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
  transition: transform 240ms var(--app-ease);
}
.app-film-play svg { width: 34px; height: 34px; }
@media (pointer: fine) { .app-film-play:hover span { transform: scale(1.05); } }
.app-film-note { text-align: center; margin: 18px 0 0; font: 500 0.88rem/1.5 'Montserrat', sans-serif; color: var(--app-sub-dark); }

/* ==========================================================================
   APP PAGE — free vs premium
   ========================================================================== */

.app-plans { display: grid; gap: 24px; }
@media (min-width: 900px) { .app-plans { grid-template-columns: 1fr 1fr; align-items: start; } }
.app-plan { border-radius: var(--app-r-xl); padding: 32px 28px; background: #fff; box-shadow: inset 0 0 0 1px var(--app-line), 0 20px 50px -30px rgba(10, 25, 48, 0.25); }
.app-plan h3 { font-size: 1.7rem; margin: 0 0 4px; }
.app-plan-sub { margin: 0 0 22px; color: var(--app-muted); font-weight: 500; }
.app-plan-premium { background: linear-gradient(165deg, var(--app-navy-deep), var(--app-navy)); color: #e5e7eb; box-shadow: 0 30px 60px -30px rgba(10, 25, 48, 0.6); }
.app-plan-premium h3 { color: #fff; }
.app-plan-premium .app-plan-sub { color: var(--app-sub-dark); }
.app-plan-premium .app-ticks li::before { background-color: var(--app-gold); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.5 10.5l3 3 6-7' fill='none' stroke='%230a1930' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.app-plan-shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 26px 0 22px; }
.app-plan-shots figure { margin: 0; }
.app-plan-shots .app-phone { padding: 12px 5px 6px; border-radius: 22px; }
.app-plan-shots .app-phone::before { top: 4px; width: 5px; height: 5px; margin-left: -2.5px; }
.app-plan-shots .app-screen { border-radius: 16px; }
.app-plan-shots figcaption { text-align: center; margin-top: 8px; font: 600 0.78rem/1.3 'Montserrat', sans-serif; color: var(--app-sub-dark); }
.app-plan-small { font-size: 0.86rem; line-height: 1.6; color: var(--app-sub-dark); margin: 0; }

/* ==========================================================================
   APP PAGE — promise, FAQ, final CTA
   ========================================================================== */

.app-promise { display: grid; gap: 18px; }
@media (min-width: 768px) { .app-promise { grid-template-columns: repeat(3, 1fr); } }
.app-promise li { list-style: none; padding: 28px 24px; border-radius: var(--app-r-lg); background: #fff; box-shadow: inset 0 0 0 1px var(--app-line); }
.app-promise-icon {
  width: 48px; height: 48px; border-radius: 14px; margin-bottom: 16px;
  display: flex; align-items: center; justify-content: center;
  background: var(--app-gold-soft); color: var(--app-gold-ink);
}
.app-promise-icon svg { width: 24px; height: 24px; }
.app-promise h3 { font-size: 1.25rem; margin: 0 0 6px; }
.app-promise p { margin: 0; line-height: 1.6; }
.app-credits { text-align: center; margin: 28px 0 0; font-size: 0.9rem; color: var(--app-muted); }
.app-credits a { color: #6f4c08; font-weight: 600; } /* #9a6b12 measured 4.4:1 on the cream band; #6f4c08 is the tree's darker gold */

.app-faq { max-width: 820px; margin: 0 auto; display: grid; gap: 12px; }
.app-faq details { border-radius: var(--app-r-lg); background: #fff; box-shadow: inset 0 0 0 1px var(--app-line); }
.app-faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 20px 22px; font: 700 1.02rem/1.4 'Montserrat', sans-serif; color: var(--app-ink);
}
.app-faq summary::-webkit-details-marker { display: none; }
.app-faq summary::after {
  content: ""; flex: none; width: 28px; height: 28px; border-radius: 50%;
  background: var(--app-gold-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 5v10M5 10h10' fill='none' stroke='%239a6b12' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center/14px no-repeat;
  transition: transform 300ms var(--app-ease);
}
.app-faq details[open] summary::after { transform: rotate(45deg); }
.app-faq details > div { padding: 0 22px 20px; line-height: 1.7; }
.app-faq details > div p { margin: 0 0 10px; }
.app-faq details > div p:last-child { margin: 0; }

.app-final {
  position: relative; overflow: clip;
  border-radius: 32px; padding: 64px 24px; text-align: center; color: #fff;
  background:
    radial-gradient(600px 300px at 50% 0%, rgba(255, 255, 255, 0.14), transparent 70%),
    linear-gradient(165deg, var(--app-sky-1), var(--app-sky-2));
}
.app-final img.app-final-icon { width: 84px; height: 84px; border-radius: 20px; margin: 0 auto 20px; display: block; box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35); }
.app-final h2 { color: #fff; font-size: clamp(2.2rem, 5vw, 3.6rem); line-height: 1.05; margin: 0 0 14px; }
.app-final p { color: #e5e7eb; margin: 0 auto 26px; max-width: 520px; line-height: 1.6; }
.app-final .app-cta-row { justify-content: center; }
.app-final .app-qr { margin: 28px auto 0; text-align: left; }
.app-back { text-align: center; margin: 36px 0 0; }

/* Mobile download bar. Without JS it simply stays visible (the page reserves
   room for it); with JS it hides while the hero or final CTA is on screen. */
.app-getbar {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 90;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 10px 10px 12px; border-radius: 20px;
  background: rgba(10, 25, 48, 0.96); color: #fff;
  box-shadow: 0 18px 40px rgba(10, 25, 48, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  transition: transform 400ms var(--app-ease), opacity 400ms var(--app-ease);
}
.app-getbar img.app-getbar-icon { width: 40px; height: 40px; border-radius: 10px; flex: none; }
.app-getbar-text { flex: 1; min-width: 0; font-family: 'Montserrat', sans-serif; }
.app-getbar-text strong { display: block; font-size: 0.95rem; line-height: 1.2; }
.app-getbar-text span { display: block; font-size: 0.76rem; color: var(--app-sub-dark); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-getbar .app-badge img { width: 128px; }
.app-getbar.is-hidden { transform: translateY(140%); opacity: 0; pointer-events: none; }
.app-page-has-getbar { padding-bottom: 92px; }
@media (min-width: 768px) {
  .app-getbar { display: none; }
  .app-page-has-getbar { padding-bottom: 0; }
}

/* ==========================================================================
   /apps/ — the showcase
   ========================================================================== */

.apps-hero {
  position: relative; overflow: clip; color: #fff; text-align: center;
  padding: 88px 0 120px;
  background:
    radial-gradient(700px 360px at 50% 0%, rgba(212, 168, 75, 0.18), transparent 70%),
    linear-gradient(180deg, var(--app-navy-deep), var(--app-navy));
}
.apps-hero h1 { color: #fff; font-size: clamp(2.6rem, 6.5vw, 4.6rem); line-height: 1.04; letter-spacing: -0.02em; margin: 18px auto 18px; max-width: 900px; }
.apps-hero h1 em { color: var(--app-gold); }
.apps-hero p { color: var(--app-sub-dark); font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.7; max-width: 640px; margin: 0 auto; }
.apps-hero .app-crumbs { margin-bottom: 36px; }
.apps-hero .app-crumbs ol { justify-content: center; }

.apps-list { margin-top: -72px; position: relative; display: grid; gap: 28px; }
.apps-grid-2 { display: grid; gap: 28px; }
@media (min-width: 900px) { .apps-grid-2 { grid-template-columns: 1fr 1fr; } }

.app-card {
  position: relative; overflow: clip;
  border-radius: 32px; color: #fff;
  background: linear-gradient(160deg, var(--app-sky-1), var(--app-sky-2));
  box-shadow: 0 40px 80px -40px rgba(10, 25, 48, 0.55);
  transition: transform 500ms var(--app-ease), box-shadow 500ms var(--app-ease);
}
@media (pointer: fine) { .app-card-feature:hover { transform: translateY(-4px); box-shadow: 0 50px 90px -40px rgba(10, 25, 48, 0.65); } }

.app-card-feature { display: grid; }
@media (min-width: 900px) { .app-card-feature { grid-template-columns: 1.1fr 0.9fr; min-height: 520px; } }
.app-card-body { position: relative; z-index: 1; padding: 40px 28px; display: flex; flex-direction: column; justify-content: center; }
@media (min-width: 768px) { .app-card-body { padding: 56px 52px; } }
.app-card .app-id { margin-bottom: 18px; }
.app-card h2 { color: #fff; font-size: clamp(2.2rem, 4.6vw, 3.5rem); line-height: 1.04; letter-spacing: -0.02em; margin: 0 0 14px; }
.app-card h2 .app-hl { color: var(--app-accent-light); font-style: italic; }
.app-card-desc { color: #e5e7eb; font-size: 1.05rem; line-height: 1.65; margin: 0 0 20px; max-width: 520px; }
.app-card .app-chips { margin-bottom: 28px; }
.app-card .app-cta-row { gap: 14px; }
.app-card .app-badge img { width: 172px; }

.app-card-visual { position: relative; min-height: 360px; display: flex; align-items: flex-end; justify-content: center; overflow: clip; }
.app-card-visual .app-phone { position: absolute; max-width: 230px; width: 54%; }
.app-card-visual .app-phone-back { right: 6%; bottom: -12%; transform: rotate(8deg); opacity: 0.9; }
.app-card-visual .app-phone-front { left: 10%; bottom: -20%; transform: rotate(-4deg); }
@media (min-width: 900px) {
  .app-card-visual { min-height: 0; }
  .app-card-visual .app-phone { width: 230px; }
  .app-card-visual .app-phone-back { right: 4%; bottom: -10%; }
  .app-card-visual .app-phone-front { left: 6%; bottom: -16%; }
}
@media (max-width: 899px) { .app-card-visual { height: 380px; } }

.app-card-soon .app-card-art { position: relative; aspect-ratio: 1024 / 500; overflow: hidden; }
.app-card-soon .app-card-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.app-card-soon .app-card-body { padding: 30px 28px 34px; }
.app-card-soon h2 { font-size: clamp(1.9rem, 3vw, 2.4rem); }
.app-status {
  display: inline-flex; align-items: center; gap: 8px; align-self: flex-start;
  padding: 6px 12px; border-radius: 999px; margin-bottom: 16px;
  background: rgba(255, 215, 154, 0.14); color: var(--app-accent-light);
  font: 700 0.76rem/1.2 'Montserrat', sans-serif; letter-spacing: 0.1em; text-transform: uppercase;
}
.app-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

.app-card-next {
  color: var(--app-ink);
  background: var(--app-cream);
  box-shadow: inset 0 0 0 2px var(--app-line);
  display: flex; align-items: center;
}
.app-card-next .app-card-body { align-items: flex-start; }
.app-card-next h2 { color: var(--app-ink); font-size: clamp(1.7rem, 2.6vw, 2.1rem); }
.app-card-next p { color: var(--app-body); line-height: 1.7; margin: 0 0 22px; max-width: 460px; }
.app-next-icon { width: 56px; height: 56px; border-radius: 16px; margin-bottom: 20px; display: flex; align-items: center; justify-content: center; background: var(--app-gold-soft); color: var(--app-gold-ink); }
.app-next-icon svg { width: 28px; height: 28px; }

.apps-cta { display: grid; gap: 22px; align-items: center; padding: 40px 28px; border-radius: 28px; background: var(--app-cream); box-shadow: inset 0 0 0 1px #E9DCC5; }
@media (min-width: 900px) { .apps-cta { grid-template-columns: 1fr auto; padding: 44px 52px; } }
.apps-cta h2 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin: 0 0 8px; }
.apps-cta p { margin: 0; line-height: 1.7; max-width: 620px; }

/* ==========================================================================
   Entrance reveals (once, on first scroll into view). Gated by html.app-js.
   ========================================================================== */

.app-js [data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity 900ms var(--app-ease), transform 1000ms var(--app-ease); }
.app-js [data-reveal="right"] { transform: translateX(36px); }
.app-js [data-reveal="rise"] { transform: translateY(60px) scale(0.97); }
.app-js [data-reveal].is-in { opacity: 1; transform: none; }
.app-js [data-reveal-delay="1"] { transition-delay: 150ms; }
.app-js [data-reveal-delay="2"] { transition-delay: 300ms; }
.app-js [data-reveal-delay="3"] { transition-delay: 600ms; }
.app-js [data-reveal-delay="4"] { transition-delay: 900ms; }

@media (prefers-reduced-motion: reduce) {
  .app-js [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .app-tour-js .app-step-text { transition: none !important; transform: none !important; }
  .app-stage .app-screen > * { transition: none !important; transform: none !important; }
  .app-card, .app-btn, .app-badge, .app-getbar { transition: none !important; }
}

/* ==========================================================================
   App themes — each app's own colours (see TOKENS above).
   ========================================================================== */

.app-theme-forecastpal {
  --app-accent: #3b82f6;
  --app-accent-ink: #1d3fad;
  --app-accent-light: #bfdbfe;
  --app-sky-1: #0f172b;
  --app-sky-2: #1d3fad;
  --app-glow: rgba(59, 130, 246, 0.45); /* #3b82f6 */
}

.app-theme-glowmerge {
  --app-accent: #ffd79a;
  --app-accent-ink: #34263b;
  --app-accent-light: #ffd79a;
  --app-sky-1: #0c0f2b;
  --app-sky-2: #34263b;
  --app-glow: rgba(255, 215, 154, 0.3); /* #ffd79a */
}
