/* Cargo Tilt — one stylesheet. No framework, no web fonts, no trackers.
   Visual language: design/ART_DIRECTION_V2.md — glossy toy harbour.
   Every colour here is measured off the reference icon or taken from the
   game palette (art/compose/palette.py). The hero scene is inline SVG
   generated by art/compose/web_hero.py; its animation lives at the bottom
   of this file so the scene file itself stays free of style attributes
   (the site ships style-src 'self'). */

:root {
  color-scheme: light dark;

  /* --- scene colours, shared with the SVG ------------------------------ */
  --sky-top:   #3E9FF3;
  --sky-mid:   #79CCFB;
  --sky-low:   #C6EBFD;
  --sea:       #0A82D6;
  --sea-deep:  #0458AF;
  --sea-ink:   #05346B;
  --hull:      #123A7B;
  --sun:       #FFDE4E;
  --crate:     #FFCE22;
  --red:       #E44036;

  /* --- page ------------------------------------------------------------ */
  --page:      #EFF7FD;
  --card:      #FFFFFF;
  --card-2:    #F7FBFE;
  --ink:       #0E2440;
  --ink-soft:  #4A6076;
  --line:      #CFE0EE;
  --link:      #0A5F8A;
  --focus:     #0A5F8A;
  --on-sea:    #F4FCFF;
  --on-sea-soft:#C6E6FA;
  --on-sea-link:#BDE6FF;
  --alert:     #B3261E;
  --alert-bg:  #FDECEA;

  --radius:    20px;
  --radius-s:  12px;
  --wrap:      66rem;

  /* the glossy-toy elevation: a tight contact shadow plus a soft ambient
     one, never a single flat drop shadow */
  --lift: 0 1px 0 rgba(255,255,255,.9) inset,
          0 1px 2px rgba(10,44,80,.10),
          0 10px 24px -12px rgba(10,44,80,.30);
}

@media (prefers-color-scheme: dark) {
  :root {
    --sky-top:  #0B2C50;
    --sky-mid:  #124572;
    --sky-low:  #1B5E8E;
    --sea:      #0A3F6B;
    --sea-deep: #072B4C;
    --sea-ink:  #041C33;
    --sun:      #F6C445;
    --page:     #0A1824;
    --card:     #14293A;
    --card-2:   #102130;
    --ink:      #E6F1F8;
    --ink-soft: #A6BECE;
    --line:     #26404F;
    --link:     #8FD4FF;
    --focus:    #8FD4FF;
    --on-sea:   #EAF6FF;
    --on-sea-soft:#A9C9DF;
    --on-sea-link:#BDE6FF;
    --alert:    #FF9B90;
    --alert-bg: #33201E;
    --lift: 0 1px 0 rgba(255,255,255,.06) inset,
            0 1px 2px rgba(0,0,0,.4),
            0 10px 24px -12px rgba(0,0,0,.6);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font: 1rem/1.62 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  overflow-wrap: break-word;
}

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: 1.15rem; }
img, svg { max-width: 100%; height: auto; }

a { color: var(--link); text-underline-offset: .18em; }
a:focus-visible, .skip:focus {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 6px;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--card); color: var(--ink);
  padding: .6rem 1rem; z-index: 20; border-radius: 0 0 10px 0;
}
.skip:focus { left: 0; }

/* ---------- header / footer ---------- */

.site-head {
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
}
.head-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 3.6rem;
}
.brand {
  display: inline-flex; align-items: center; gap: .6rem;
  font-weight: 800; font-size: 1.08rem; letter-spacing: -.01em;
  color: var(--ink); text-decoration: none;
}
.brand img { border-radius: 8px; box-shadow: 0 1px 3px rgba(10,44,80,.28); }
.lang-switch {
  font-size: .9rem; font-weight: 700; text-decoration: none;
  color: var(--link);
  border: 1px solid var(--line); border-radius: 999px;
  padding: .38rem .95rem; background: var(--card-2);
}
.lang-switch:hover { border-color: var(--focus); }

.site-foot {
  background: var(--card);
  border-top: 1px solid var(--line);
  padding-block: 1.8rem 2.4rem;
  font-size: .92rem; color: var(--ink-soft);
}
.site-foot nav { display: flex; flex-wrap: wrap; gap: 1.3rem; margin-bottom: .85rem; }
.site-foot nav a { font-weight: 700; }
.site-foot p { margin: 0; max-width: 46rem; }

/* ================= landing: the hero ================= */

.hero {
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 52%,
                                      var(--sky-low) 100%);
  padding-block: 3rem 3.2rem;
  position: relative;
}
.hero-copy { max-width: 40rem; text-align: center; margin-inline: auto; }
.hero h1 {
  font-size: clamp(2.4rem, 9vw, 4.1rem);
  line-height: 1.02; letter-spacing: -.028em; font-weight: 800;
  margin: 0 0 .45rem;
  color: #0B2450;
  text-shadow: 0 1px 0 rgba(255,255,255,.55);
}
/* No opacity here: 86 % of the ink over the sky gradient measures 4.30:1,
   and at 16.8 px bold this is not "large text". Solid ink measures 5.40:1. */
.hero .tagline {
  font-size: clamp(1.05rem, 3.4vw, 1.3rem); font-weight: 700;
  color: #0B2450; margin: 0 0 1rem;
}
.hero .pitch {
  font-size: clamp(1rem, 2.6vw, 1.12rem);
  color: #0B2450; margin: 0 auto 1.4rem; max-width: 34rem;
}

@media (prefers-color-scheme: dark) {
  .hero h1, .hero .tagline, .hero .pitch { color: #EAF6FF; text-shadow: none; }
}

/* the app icon, seated the way a store listing seats it */
.hero-icon {
  display: block; margin: 0 auto .9rem;
  width: clamp(72px, 16vw, 96px); height: auto;
  border-radius: 22.37%;             /* the iOS squircle's nearest CSS cousin */
  box-shadow: 0 2px 4px rgba(6,32,62,.18), 0 14px 30px -12px rgba(6,32,62,.55);
}

/* ---------- store badges ----------
   Both are always drawn in full. Only the wrapper changes: an <a> when
   site.config.json has the listing URL, an inert <span> when it does not.
   Nothing here ever renders an <a> without an href. */

.badges {
  display: flex; flex-wrap: wrap; gap: .75rem;
  justify-content: center; margin: 1.7rem 0 .4rem;
}
.badge { display: inline-flex; border-radius: 8px; text-decoration: none; }
.badge .bg-art { display: block; height: 52px; width: auto; }
.badge .bg-plate { fill: #000; stroke: rgba(255,255,255,.55); stroke-width: 1; }
.badge .bg-mark { fill: #FFF; }
.badge .bg-s {
  fill: #FFF; font-size: 8.4px; letter-spacing: .012em;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
.badge .bg-b {
  fill: #FFF; font-size: 16.4px; font-weight: 600; letter-spacing: -.012em;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
a.badge { transition: transform .18s ease, box-shadow .18s ease; }
a.badge:hover { transform: translateY(-2px); box-shadow: 0 10px 20px -10px rgba(0,0,0,.7); }
a.badge:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* no destination yet: complete artwork, nothing to click, nothing to focus */
.badge.is-idle { cursor: default; -webkit-user-select: none; user-select: none; }
@media (min-width: 52rem) { .badge .bg-art { height: 56px; } }

/* the key art, framed as the toy object it is: one rounded plate, one contact
   shadow, one ambient shadow. It is cropped, never letterboxed — the SVG uses
   xMidYMax slice, so a wide window loses sky, never the ship or the meter. */
.hero-art {
  margin: 0 auto; max-width: 62rem;
  border-radius: 26px; overflow: hidden;
  box-shadow: 0 2px 0 rgba(255,255,255,.35) inset,
              0 6px 14px -6px rgba(5,36,72,.35),
              0 28px 60px -28px rgba(5,36,72,.65);
}
.hero-scene { display: block; width: 100%; height: clamp(320px, 44vw, 500px); }
.hero-cap {
  background: var(--sea-deep); color: var(--on-sea-soft);
  margin: 0; font-size: .84rem; text-align: center;
  padding: .7rem 1.15rem .85rem;
}

/* ---- the scene at dusk: only the sky, sea and haze change hands; the paint,
   the foam and the containers keep their own colour, the way they would. ---- */
@media (prefers-color-scheme: dark) {
  .sky0  { stop-color: #0E3358; }
  .sky1  { stop-color: #1B5A87; }
  .sky2  { stop-color: #2E7BA4; }
  .sun0  { stop-color: #FFEFAE; }
  .sun1  { stop-color: #FFA93A; }
  .cloud0{ stop-color: #A9C9E0; }
  .cloud1{ stop-color: #6E96B8; }
  .cloud-base { fill: #6E96B8; }
  .sea0  { stop-color: #1E6F9E; }
  .sea1  { stop-color: #0D4E7C; }
  .sea2  { stop-color: #07355A; }
  .sea3  { stop-color: #4E9BBE; }
  .haze0 { stop-color: #3F6F92; }
  .haze1 { stop-color: #2F5B7C; }
  .land0 { stop-color: #5E8F58; }
  .land1 { stop-color: #3E6B44; }
  .horizon-foam { fill: #9FC8DC; opacity: .3; }
}

/* ================= sections ================= */

section { padding-block: 3rem; }
section > .wrap > h2 {
  font-size: clamp(1.45rem, 5vw, 2rem); letter-spacing: -.02em;
  margin: 0 0 .45rem; line-height: 1.15;
}
section > .wrap > .lede { color: var(--ink-soft); margin: 0 0 1.7rem; max-width: 42rem; }

/* the deep-water band: the page's one dark section, straight out of the scene */
.deep {
  background: linear-gradient(180deg, var(--sea-deep) 0%, var(--sea-ink) 100%);
  color: var(--on-sea);
  padding-block: 2.2rem 3.2rem;
}
.deep > .wrap > h2 { color: var(--on-sea); }
.deep > .wrap > .lede { color: var(--on-sea-soft); }
.deep a { color: var(--on-sea-link); }
.deep .motion-note { color: var(--on-sea-soft); }

/* ---------- cards ---------- */

.anim-grid, .shot-grid {
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr));
}
.anim-grid > *, .shot-grid > *, .hero-copy > * { min-width: 0; }

.anim-card, .shot {
  background: var(--card);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column; margin: 0;
  box-shadow: var(--lift);
}
.anim-card img, .shot img {
  display: block; width: 100%; height: auto;
  background: var(--sky-low);
}
.anim-card figcaption, .shot figcaption {
  padding: .9rem 1.05rem 1.1rem; font-size: .93rem; color: var(--ink-soft);
}
.anim-card figcaption b, .shot figcaption b {
  color: var(--ink); display: block; font-size: 1.02rem; margin-bottom: .15rem;
}

.motion-note { font-size: .88rem; color: var(--ink-soft); margin: 1.4rem 0 0; }

/* ---------- "what's on board" ---------- */

.board { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
         list-style: none; margin: 0; padding: 0; }
.board li {
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--radius-s); padding: .95rem 1.1rem;
  font-size: .95rem; color: var(--ink-soft);
}
.board li b { display: block; color: var(--ink); font-size: 1rem; margin-bottom: .1rem; }

/* ---------- honest list ---------- */

.honest { background: var(--card); border-block: 1px solid var(--line); }
.honest ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.05rem; }
.honest li { padding-left: 2.3rem; position: relative; max-width: 46rem; }
.honest li::before {
  content: "✕"; position: absolute; left: 0; top: -.02rem;
  color: var(--alert); font-weight: 800; font-size: 1.1rem;
  width: 1.6rem; text-align: center;
}
.honest li b { display: block; }
.honest .ads-note { margin-top: 1.8rem; max-width: 46rem; color: var(--ink-soft); font-size: .95rem; }

/* ---------- prose (legal + support) ---------- */

.prose { max-width: 44rem; margin-inline: auto; padding: 2.2rem 1.15rem 1rem; }
.prose h1 { font-size: clamp(1.7rem, 6vw, 2.3rem); line-height: 1.18; margin: 0 0 1.2rem;
            letter-spacing: -.02em; }
.prose h2 { font-size: 1.28rem; margin: 2.3rem 0 .6rem; padding-top: .7rem;
            border-top: 1px solid var(--line); }
.prose h3 { font-size: 1.06rem; margin: 1.6rem 0 .4rem; }
.prose ul { padding-left: 1.3rem; }
.prose li { margin-bottom: .45rem; }
.prose code {
  background: var(--card-2); border: 1px solid var(--line); color: var(--ink);
  padding: .1em .35em; border-radius: 5px; font-size: .9em;
}
.prose .back { margin-top: 2.6rem; font-weight: 700; }

.table-wrap { overflow-x: auto; margin: 1rem 0; }
.prose table { border-collapse: collapse; min-width: 32rem; font-size: .92rem; }
.prose th, .prose td {
  border: 1px solid var(--line); padding: .55rem .7rem;
  text-align: left; vertical-align: top;
}
.prose th { background: var(--card-2); }

/* Unfilled [PLACEHOLDER] from the legal drafts — must stay impossible to miss. */
mark.ph {
  background: #FFF3C4; color: #5B4500;
  border: 1px dashed #B98900; border-radius: 5px;
  padding: 0 .3em; font-weight: 700; font-size: .95em;
}
@media (prefers-color-scheme: dark) {
  mark.ph { background: #3A3218; color: #FFE08A; border-color: #B98900; }
}

/* DRAFT — NOT LEGAL ADVICE banners lifted from the markdown blockquotes. */
.draft {
  background: var(--alert-bg);
  border: 1px solid var(--alert); border-left-width: 5px;
  border-radius: 12px; padding: 1rem 1.15rem; margin: 1.5rem 0; font-size: .93rem;
}
.draft > :first-child { margin-top: 0; }
.draft > :last-child { margin-bottom: 0; }
.draft strong { color: var(--alert); }

/* ---------- support ---------- */

.todo {
  display: inline-block;
  background: #FFF3C4; color: #5B4500;
  border: 1px dashed #B98900; border-radius: 6px;
  padding: .15em .5em; font-weight: 700;
}
@media (prefers-color-scheme: dark) { .todo { background: #3A3218; color: #FFE08A; } }
.callout {
  background: var(--card-2); border: 1px solid var(--line);
  border-left: 5px solid var(--sea);
  border-radius: 12px; padding: 1rem 1.15rem; margin: 1.5rem 0;
}
.callout > :first-child { margin-top: 0; }
.callout > :last-child { margin-bottom: 0; }
.support-shot {
  max-width: 15rem; margin: 1rem auto; display: block;
  border-radius: var(--radius); box-shadow: var(--lift);
}

@media (min-width: 52rem) {
  .hero { padding-block: 4.2rem 0; }
  section { padding-block: 4rem; }
}

/* =====================================================================
   MOTION
   Two kinds only:
   1. the hero scene's single 13 s loop — every part shares one timeline,
      so the ship, the crates and the tilt meter can never drift apart;
   2. a one-shot entrance for each block as it scrolls in.
   Both are switched off wholesale at the bottom of this file, where the
   scene is frozen on the one frame that carries the whole idea.
   ===================================================================== */

.js .reveal { opacity: 0; transform: translateY(18px);
              transition: opacity .55s ease, transform .55s cubic-bezier(.22,.72,.3,1); }
.js .reveal.in { opacity: 1; transform: none; }
.js .reveal.d1 { transition-delay: .07s; }
.js .reveal.d2 { transition-delay: .14s; }
.js .reveal.d3 { transition-delay: .21s; }

/* ---- the scene ------------------------------------------------------- */

.ship {
  transform-box: view-box; transform-origin: 470px 452px;
  animation: heel 13s cubic-bezier(.36,.06,.24,1) infinite;
}
.fly { transform-box: fill-box; transform-origin: 50% 100%; }
.fly-a { animation: fly-a 13s cubic-bezier(.3,.05,.3,1) infinite; }
.fly-b { animation: fly-b 13s cubic-bezier(.3,.05,.3,1) infinite; }
.fly-c { animation: fly-c 13s cubic-bezier(.3,.05,.3,1) infinite; }
.fly-d { animation: fly-d 13s cubic-bezier(.3,.05,.3,1) infinite; }
.gauge-marker {
  transform-box: view-box; transform-origin: 450px 526px;
  animation: meter 13s cubic-bezier(.36,.06,.24,1) infinite;
}
.gauge-amber { animation: amber 13s linear infinite; }
.sun-glow { transform-box: view-box; transform-origin: 742px 118px;
            animation: breathe 9s ease-in-out infinite; }
.cloud { transform-box: view-box; }
.c1 { animation: drift 78s linear infinite; }
.c2 { animation: drift 112s linear infinite; }
.c3 { animation: drift 94s linear infinite; }
.wave { transform-box: view-box; }
.w1 { animation: crawl 17s linear infinite; }
.w2 { animation: crawl 23s linear infinite reverse; }
.w3 { animation: crawl 29s linear infinite; }
.swell { transform-box: view-box; }
.s1 { animation: bob 7s ease-in-out infinite; }
.s2 { animation: bob 9.5s ease-in-out infinite reverse; }
.foam { transform-box: view-box; transform-origin: 470px 466px;
        animation: wash 5.5s ease-in-out infinite; }

/* The ship's heel. Timings below are shared by every other keyframe set:
   crate lands -> ship swings. 1 s = 7.69 %. */
@keyframes heel {
  0%,   14.6% { transform: rotate(0deg); }
  20%,  33.1% { transform: rotate(-6deg); }   /* A aboard, list to port   */
  38.5%, 51.5% { transform: rotate(5deg); }   /* B aboard, back to stbd   */
  57.7%       { transform: rotate(12.4deg); } /* C aboard — nearly over   */
  60.8%       { transform: rotate(10.4deg); }
  63.2%       { transform: rotate(12.8deg); }
  66.2%, 77.7% { transform: rotate(7.5deg); } /* she rights herself       */
  83.8%, 93.8% { transform: rotate(1deg); }   /* D aboard, level again    */
  100%        { transform: rotate(0deg); }
}

@keyframes meter {
  0%,   14.6% { transform: translateX(0); }
  20%,  33.1% { transform: translateX(-58px); }
  38.5%, 51.5% { transform: translateX(48px); }
  57.7%       { transform: translateX(118px); }
  60.8%       { transform: translateX(100px); }
  63.2%       { transform: translateX(122px); }
  66.2%, 77.7% { transform: translateX(72px); }
  83.8%, 93.8% { transform: translateX(10px); }
  100%        { transform: translateX(0); }
}

/* the amber shoulders brighten only while the marker is actually in them */
@keyframes amber {
  0%, 53%   { opacity: 1; }
  57.7%     { opacity: 1; filter: brightness(1.25); }
  66.2%     { opacity: 1; filter: brightness(1); }
  100%      { opacity: 1; }
}

@keyframes fly-a {
  0%, 7.6%  { opacity: 0; transform: translate(-380px, 200px) rotate(-24deg) scale(.84); }
  7.7%      { opacity: 1; transform: translate(-380px, 200px) rotate(-24deg) scale(.84); }
  11.2%     { opacity: 1; transform: translate(-190px, -46px) rotate(-11deg) scale(.94); }
  14.6%     { opacity: 1; transform: translate(0, 0) rotate(0) scale(1.07, .9); }
  16.4%     { opacity: 1; transform: none; }
  93.8%     { opacity: 1; transform: none; }
  95.8%     { opacity: 0; transform: translateY(-30px) scale(.78); }
  100%      { opacity: 0; transform: translateY(-30px) scale(.78); }
}
@keyframes fly-b {
  0%, 26.1% { opacity: 0; transform: translate(-540px, 200px) rotate(-24deg) scale(.84); }
  26.2%     { opacity: 1; transform: translate(-540px, 200px) rotate(-24deg) scale(.84); }
  29.7%     { opacity: 1; transform: translate(-270px, -56px) rotate(-11deg) scale(.94); }
  33.1%     { opacity: 1; transform: translate(0, 0) rotate(0) scale(1.07, .9); }
  34.9%     { opacity: 1; transform: none; }
  94.6%     { opacity: 1; transform: none; }
  96.6%     { opacity: 0; transform: translateY(-30px) scale(.78); }
  100%      { opacity: 0; transform: translateY(-30px) scale(.78); }
}
@keyframes fly-c {
  0%, 44.5% { opacity: 0; transform: translate(-540px, 262px) rotate(-24deg) scale(.84); }
  44.6%     { opacity: 1; transform: translate(-540px, 262px) rotate(-24deg) scale(.84); }
  48.1%     { opacity: 1; transform: translate(-270px, -34px) rotate(-11deg) scale(.94); }
  51.5%     { opacity: 1; transform: translate(0, 0) rotate(0) scale(1.07, .9); }
  53.3%     { opacity: 1; transform: none; }
  95.4%     { opacity: 1; transform: none; }
  97.4%     { opacity: 0; transform: translateY(-30px) scale(.78); }
  100%      { opacity: 0; transform: translateY(-30px) scale(.78); }
}
@keyframes fly-d {
  0%, 70.7% { opacity: 0; transform: translate(-380px, 262px) rotate(-24deg) scale(.84); }
  70.8%     { opacity: 1; transform: translate(-380px, 262px) rotate(-24deg) scale(.84); }
  74.3%     { opacity: 1; transform: translate(-190px, -34px) rotate(-11deg) scale(.94); }
  77.7%     { opacity: 1; transform: translate(0, 0) rotate(0) scale(1.07, .9); }
  79.5%     { opacity: 1; transform: none; }
  96.2%     { opacity: 1; transform: none; }
  98.2%     { opacity: 0; transform: translateY(-30px) scale(.78); }
  100%      { opacity: 0; transform: translateY(-30px) scale(.78); }
}

@keyframes drift  { from { transform: translateX(-140px); } to { transform: translateX(980px); } }
@keyframes crawl  { from { transform: translateX(0); }      to { transform: translateX(-150px); } }
@keyframes bob    { 0%,100% { transform: translateY(0); }   50% { transform: translateY(-5px); } }
@keyframes wash   { 0%,100% { transform: scale(1); opacity: 1; }
                    50%     { transform: scale(1.03, .92); opacity: .88; } }
@keyframes breathe{ 0%,100% { transform: scale(1); opacity: 1; }
                    50%     { transform: scale(1.08); opacity: .8; } }

/* ---------- reduced motion: nothing moves, and the still frame is the
     one that carries the idea — fully loaded, heeled hard over, the tilt
     meter sitting in the amber. ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition-duration: .001ms !important;
  }
  .js .reveal { opacity: 1 !important; transform: none !important; }
  .ship         { transform: rotate(11deg) !important; }
  .fly          { opacity: 1 !important; transform: none !important; }
  .gauge-marker { transform: translateX(114px) !important; }
}
