/* thedesti.app, the homepage.
   The section rhythm is the App Store set's own: cream and olive panels in turn,
   each with a Fraunces headline whose second run is the accent, and the real app.
   Tokens live in v2.css (the App Store panel renderer's themes, exactly). */

:root {
  --olive-a: #6B8A2A;            /* olive panel, top (the panel theme's c1) */
  --olive-b: #4E661F;            /* olive panel, bottom (c2) */
  --gold: #F4E3B8;               /* the olive theme's accent run */
  --tan-2: rgba(250, 238, 218, .9);
  --map-water: #6dd3e7; --map-land-2: #95dfc1; --map-land-3: #a8e6cc; --map-land-4: #bbecd9;
  --map-border: #7d9e90; --map-admin1: #8fa49c; --map-label: #5c6360; --map-sea: #1c7f92;
  --line: var(--rule); --ink-soft: var(--sub); --ease-out: cubic-bezier(.16, 1, .3, 1);
  --section: clamp(88px, 11vw, 150px);
}

.wrap { width: min(1240px, 100% - 2 * var(--gutter)); margin-inline: auto; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------- headings: the panels' own construction ---------- */
.h2 { margin: 0; font: 700 clamp(2.4rem, 1.4rem + 2.8vw, 4rem)/1.02 var(--display); font-variation-settings: "opsz" 36; letter-spacing: -0.012em; color: var(--ink); text-wrap: balance; }
.h2 .acc { color: var(--olive); }
.psub { margin: 18px 0 0; max-width: 40ch; font: 400 clamp(1.125rem, 1rem + .3vw, 1.25rem)/1.5 var(--text); color: var(--sub); text-wrap: pretty; }

/* ---------- olive panels: cream words, gold accent run (large text only: 3.46:1 is AA at this size) ---------- */
.olive { background: linear-gradient(180deg, var(--olive-a) 0%, var(--olive-b) 100%); color: var(--c2); }
.olive .h2 { color: var(--c2); }
.olive .h2 .acc { color: var(--gold); }
.olive .psub { color: var(--c2); font-weight: 400; font-size: 1.5rem; line-height: 1.42; max-width: 36ch; }
.mylist__note { font-size: .875rem; }
.olive :focus-visible { outline-color: var(--c2); }
.olive .mylist :focus-visible { outline-color: var(--olive); }

/* ---------- the demo (olive): two photo cards, the app's VS, your list ---------- */
.demo { padding: var(--section) 0; }
.demo .wrap { display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: 56px; align-items: center; }
.said { margin: 28px 0 0; min-height: 2.9em; font: 600 1.5rem/1.45 var(--text); color: var(--c2); text-wrap: balance; }
.said .no { font-weight: 800; }
.skip { margin: 0; padding: 10px 4px; border: 1px solid transparent; background: none; color: var(--c2); font: 700 1.1875rem/1.2 var(--text); cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.play { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 28px; align-items: start; }
.duel { display: grid; gap: 10px; justify-items: center; }
.duel__pair { position: relative; display: grid; gap: 16px; width: 100%; }
.pcard { position: relative; display: block; width: 100%; margin: 0; padding: 0; border: 0; border-radius: 22px; overflow: hidden; cursor: pointer;
  aspect-ratio: 16 / 10; background: transparent; color: #fff; text-align: left; font: inherit; box-shadow: 0 22px 40px -24px rgba(0, 0, 0, .55);
  transition: transform 220ms var(--ease), box-shadow 160ms var(--ease), filter 300ms var(--ease); }
.pcard img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pcard::after { content: ""; position: absolute; inset: auto 0 0 0; height: 55%; background: linear-gradient(to top, rgba(10, 12, 20, .72), rgba(10, 12, 20, .28) 45%, rgba(10, 12, 20, 0)); }
.pcard__lab { position: absolute; z-index: 1; left: 18px; bottom: 14px; }
.pcard__lab b { display: block; font: 700 1.875rem/1 var(--text); text-shadow: 0 1px 3px rgba(0, 0, 0, .35); }
.pcard__lab small { display: block; margin-top: 4px; font: 500 1rem/1.2 var(--text); text-shadow: 0 1px 3px rgba(0, 0, 0, .35); }
.pcard:hover { transform: scale(1.015); }
.pcard.is-picked { box-shadow: 0 0 0 4px var(--c2), 0 22px 40px -24px rgba(0, 0, 0, .55); transform: scale(1.02); }
.pcard.is-dim { filter: brightness(.6) saturate(.7); }
.vs { position: absolute; z-index: 2; left: 50%; top: 50%; translate: -50% -50%; width: 50px; height: 50px; border-radius: 50%; display: grid; place-items: center;
  background: var(--c1); color: var(--olive-b); border: 1.5px solid #e2d3b4; font: 700 .9375rem/1 var(--text); letter-spacing: .02em; box-shadow: 0 6px 16px -8px rgba(0, 0, 0, .4); }

/* your list: the app's own rows */
.mylist { padding: 20px 18px 14px; border-radius: 24px; background: var(--c1); color: var(--ink); box-shadow: 0 28px 50px -30px rgba(0, 0, 0, .6); }
.mylist__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 4px 12px; }
.mylist h3 { margin: 0; font: 700 1.5rem/1.1 var(--display); font-variation-settings: "opsz" 36; }
.mylist__reset { padding: 8px 0; border: 1px solid transparent; background: none; color: var(--olive-b); font: 600 1rem/1 var(--text); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.mylist ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; align-content: start; }
.status { margin: -4px 4px 12px; font: 500 .9375rem/1.4 var(--text); color: var(--sub); }
.more { margin: 10px 4px 0; font: 600 .9375rem/1.4 var(--text); color: var(--ink); text-wrap: pretty; }
.more a { color: var(--olive-b); text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
.row { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 8px 12px 8px 8px; border-radius: 14px; background: #FAEEDA; }
.row__ph { position: relative; width: 48px; height: 48px; }
.row__ph img { width: 48px; height: 48px; border-radius: 10px; object-fit: cover; }
.row__n { position: absolute; left: -5px; top: -5px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px; display: grid; place-items: center;
  background: #fff; color: var(--ink); font: 700 .8125rem/1 var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, .25); }
.row:nth-child(1) .row__n { background: #DAA520; color: #1A1A2E; }
.row:nth-child(2) .row__n { background: #C9C9C9; color: #1A1A2E; }
.row:nth-child(3) .row__n { background: #CD7F32; color: #1A1A2E; }
.row__pl b { display: block; font: 600 1.0625rem/1.2 var(--text); }
.row__pl span { display: block; font: 400 .875rem/1.3 var(--text); color: var(--sub); }
.row__sc { font: 700 1.1875rem/1 var(--text); font-variant-numeric: tabular-nums; }
.row--empty { background: transparent; box-shadow: inset 0 0 0 1.5px rgba(26, 26, 46, .12); min-height: 64px; color: var(--sub); }
.row--empty .row__ph { border-radius: 10px; background: rgba(26, 26, 46, .06); }
.row--empty .row__n { background: #fff; color: var(--sub); }
.row--empty .row__pl { font: 500 1rem/1.3 var(--text); }
.mylist__note { margin: 12px 4px 0; font: 400 .875rem/1.45 var(--text); color: var(--sub); text-wrap: pretty; }
.row--empty .row__pl { text-wrap: balance; }

/* a pick that lands in the list (page.js "a pick that lands in the list"): the copy of the
   winning photo, whose resting style is its landing (the thumbnail's own box, corners and
   centered crop), the cards' names held above it while it leaves (the lids), and the old
   face of a card crossfading to its next city */
.fly { position: absolute; left: 0; top: 0; width: 48px; height: 48px; border-radius: 10px; overflow: hidden; pointer-events: none; }
.fly .fly__img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; border-radius: 0; object-fit: cover; object-position: 50% 50%; }
.fly__shade { position: absolute; inset: 0; opacity: 0; }
.fly__shade::before, .pcard__was::after { content: ""; position: absolute; inset: auto 0 0 0; height: 55%; background: linear-gradient(to top, rgba(10, 12, 20, .72), rgba(10, 12, 20, .28) 45%, rgba(10, 12, 20, 0)); }
/* a card's name while a pick plays: its lid sits in the card's own grid cell (page.js sets the cell and
   follows the card's scale), a layer above the landing row, in the card's own color and alignment, and the
   card's label waits hidden under it, so the name is drawn once and the photo passes under it */
.lid { position: absolute; z-index: 4; inset: 0; pointer-events: none; color: #fff; text-align: left; }
.lid__face { position: absolute; inset: 0; }
.pcard.is-lidded .pcard__lab { visibility: hidden; }
/* In forced colors a card's name sits on the readability backplate the browser paints, by default, in the Canvas
   color, inside the button too (the card stays transparent), so it takes the Canvas text color, on the card and in
   its lid (which holds a copy of the same label). The label needs a color of its own there. Inherited, the name on the card took the button's text color,
   which Firefox changes on hover and on press, while the lid, outside the button, took the page's: the name of the
   card under the pointer changed color when its lid came up and again when it went. And where the button text is
   not readable on Canvas (Firefox's own color override on a Mac, for one) the name could not be read at all. Only
   in an engine that forces colors, one that knows forced-color-adjust: WebKit matches the query under test
   emulation without forcing anything, and there the name stays white (measured 2026-11-05). */
@media (forced-colors: active) { @supports (forced-color-adjust: auto) { .pcard__lab { color: CanvasText; } } }
/* the landing row rides above the cards while the photo crosses to it; its own thumbnail waits under the copy */
.row.is-landing { position: relative; z-index: 3; }
.row.is-landing .row__ph { border-radius: 10px; background: rgba(26, 26, 46, .06); }
.row.is-landing .row__ph > img { visibility: hidden; }
/* a winner below the five rows shown: into the "more on your map" line, fading as it gets there */
.more { position: relative; }
.fly--away { z-index: 3; width: 21px; height: 21px; border-radius: 6px; opacity: 0; }
.pcard__was { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
/* the VS badge stays on top of the cards, so the photo leaves from under it rather than covering it */
.vs { z-index: 4; }

/* ---------- the map (cream): the earlier homepage's map, run full bleed ----------
   The page's one edge-to-edge moment. The figure sits outside .wrap (index.html), so the map is the
   section's full width with square sides; its height is the svg's own 0.39 of that width
   (562px at 1440, 749px at 1920), so every width shows the same latitudes. On a window too
   short to show that with some room above and below it (up to 96px, less on short windows),
   page-map.css caps the width and centers the map on its water. The words above it and the
   caption under it stay on the content grid. On phones the map keeps its 760px floor and
   pans from screen edge to screen edge. */
.mapsec { padding: var(--section) 0; }
.mapsec .copy { max-width: 720px; margin-bottom: 40px; }
.map__note, .map__hint { width: min(1240px, 100% - 2 * var(--gutter)); margin-inline: auto; text-wrap: pretty; }
/* a pin the frame's edge would cut, after the map panned itself: hidden until the visitor pans (map.js) */
.map__pin--edge { visibility: hidden; }
.map__frame { margin: 0; position: relative; }
/* border-radius 0 is stated, not just dropped: the global :focus-visible rule would otherwise round the map's corners on focus */
.map__scroll { overflow: auto hidden; overscroll-behavior-x: contain; border: 0; border-radius: 0; background: var(--map-water); }

/* ---------- questions and about ---------- */
.qa { padding: var(--section) 0 0; }
.faq { margin-top: 40px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: repeat(3, auto); grid-auto-flow: column; gap: 34px 72px; }
.qa-item { padding-top: 18px; border-top: 1px solid var(--rule); }
.qa-item h3 { margin: 0; font: 600 1.1875rem/1.35 var(--text); color: var(--ink); text-wrap: balance; }
.qa-item p { margin: 8px 0 0; max-width: 60ch; color: var(--sub); font-size: 1.0625rem; line-height: 1.6; text-wrap: pretty; }
.about { margin-top: var(--section); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px 72px; align-items: start;
  padding: clamp(32px, 4vw, 56px); border-radius: 32px; background: rgba(255, 253, 248, .7); box-shadow: 0 0 0 1px var(--rule); }
.about .h2 { font-size: clamp(2.375rem, 1.2rem + 2.4vw, 3.4rem); }  /* "Made in New York," fits its column on one line */
.about p { margin: 0 0 14px; color: var(--sub); }
.about a { color: var(--ink); text-underline-offset: 3px; }
.facts { margin: 22px 0 0; padding: 0; }
.facts div { display: grid; grid-template-columns: 9rem 1fr; gap: 12px; padding: 12px 0; border-top: 1px solid var(--rule); }
.facts dt { font: 600 .9375rem/1.4 var(--text); color: var(--sub); }
.facts dd { margin: 0; font: 500 1.0625rem/1.4 var(--text); overflow-wrap: anywhere; }

/* ---------- the close: App Store panel 5 (the trip photos edge to edge, the olive wordmark sitting on them) ---------- */
.close { position: relative; padding: var(--section) 0 64px; text-align: center; overflow: hidden; }
.close__top { position: relative; z-index: 2; padding-inline: var(--gutter); }
.close__mark { display: block; width: min(64%, 620px); height: auto; margin: 0 auto calc(min(64vw, 620px) * -.052); }
/* one row exactly the strip's height: an image's own 3:4 height must never push the row taller than the strip */
.close__strip { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr); height: clamp(280px, 31vw, 480px); overflow: hidden; }
.close__strip img { width: 100%; height: 100%; min-height: 0; object-fit: cover; }
.close .lockup { --lk: clamp(2.375rem, 1.4rem + 2.8vw, 4rem); margin-top: 48px; }
.close .btn { margin-top: 32px; }
.close .free { margin-top: 12px; }
.close .inner { position: relative; z-index: 2; padding-inline: var(--gutter); }

.foot { padding: 30px 0 40px; border-top: 1px solid var(--rule); }
.foot .wrap { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 32px; }
.foot nav { display: flex; flex-wrap: wrap; gap: 6px 26px; }
.foot nav a { padding: 8px 0; color: var(--ink); text-decoration: none; font: 500 1rem/1 var(--text); }
.foot nav a:hover { text-decoration: underline; text-underline-offset: 3px; }
.foot p { margin: 0; font: 400 .9375rem/1.4 var(--text); color: var(--sub); }
.foot .credit { width: 100%; font-size: .8125rem; color: rgba(90, 98, 117, .55); }

@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* ---------- phone dock: one download button on screen at a time ---------- */
.dock { display: none; }

@media (max-width: 1080px) {
  .demo .wrap { grid-template-columns: 1fr; }
  .play { grid-template-columns: 1fr 1fr; }
  .about { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  :root { --section: 76px; }
  .h2 { font-size: 2.375rem; }
  .olive .psub { font-size: 1.5rem; font-weight: 400; line-height: 1.4; }
  .demo .wrap { gap: 26px; }
  .said { margin-top: 18px; min-height: 2.9em; font-size: 1.1875rem; font-weight: 700; }
  .play { grid-template-columns: 1fr; gap: 20px; }
  .duel__pair { grid-template-columns: 1fr 1fr; gap: 10px; }
  .pcard { aspect-ratio: 3 / 4; border-radius: 18px; }
  .pcard__lab { left: 12px; bottom: 10px; }
  .pcard__lab b { font-size: 1.375rem; }
  .pcard__lab small { font-size: .875rem; }
  .vs { width: 42px; height: 42px; font-size: .8125rem; }
  .row--empty:nth-child(n+3) { display: none; }
  .faq { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; gap: 24px; }
  .facts div { grid-template-columns: 7.5rem 1fr; }
  .close__mark { width: 78%; margin-bottom: -4.1vw; }
  .close__strip { grid-template-columns: 1fr 1fr; grid-template-rows: repeat(2, 46vw); height: auto; }
  .close .lockup { margin-top: 36px; }
  .close .btn { width: 100%; }
  .dock { display: block; position: fixed; z-index: 40; left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); padding: 10px; border-radius: 24px;
    background: rgba(253, 250, 242, .94); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); box-shadow: 0 0 0 1px var(--rule), 0 14px 34px -14px rgba(26, 26, 46, .45);
    transform: translateY(150%); visibility: hidden; transition: transform 320ms var(--ease), visibility 0s linear 320ms; }
  .dock .btn { width: 100%; }
  .dock-on .dock { transform: none; visibility: visible; transition: transform 320ms var(--ease), visibility 0s; }
}
@media (prefers-reduced-motion: reduce) { .pcard, .dock, .dock-on .dock { transition: none; } }
/* On the narrowest phones each fact's label sits over its value, so the email stays on one line. */
@media (max-width: 23.75em) { .facts div { grid-template-columns: 1fr; gap: 2px; } }
@media (forced-colors: active) { .pcard, .mylist, .row, .skip, .mylist__reset { border: 1px solid CanvasText; } }
