/* sleeve-app.com — the whole stylesheet, hand-written and linked by every page.
 *
 * Built to the 1440px comp. Values below are the comp's, converted to real
 * pixels; the palette is still the app's SleeveChrome (lib/ui/theme.dart), with
 * the alphas taken from its hex alphas rather than rounded — 0x8C is .549, not
 * "about half".
 *
 * Mint stays scarce. In the app it means exactly one thing (a code has
 * settled); a web page has no viewfinder, so what carries over is only that it
 * marks the primary action, the accent word in the headline and the step marks,
 * and nothing else.
 *
 * Deliberately not Cardmarket's colours, and nowhere near its logo. */

/* Sora for headings, Inter for body and UI, Caveat for the one handwritten
 * accent. The only external request the site makes — see `_headers`. */
@import url("https://fonts.googleapis.com/css2?family=Sora:wght@400;600;700&family=Inter:wght@400;500;600&family=Caveat:wght@500&display=swap");

:root {
  --ground: #0a0a0a;

  /* SleeveChrome.base and the panels built on it. */
  --panel: rgba(28, 25, 23, 0.549); /* SleeveChrome.panel      0x8C1C1917 */
  --panel-strong: rgba(28, 25, 23, 0.812); /* panelStrong      0xCF1C1917 */
  --tile: rgba(245, 243, 240, 0.05);

  --hairline: rgba(255, 255, 255, 0.141); /* hairline          0x24FFFFFF */
  --hairline-strong: rgba(255, 255, 255, 0.161); /* hairlineStrong 0x29FFFFFF */

  --ink: #f5f3f0; /* onChrome */
  --ink-2: rgba(245, 243, 240, 0.722); /* onChromeSecondary    0xB8 */
  --ink-3: rgba(245, 243, 240, 0.62); /* onChromeMuted         0x9E */
  --ink-4: rgba(245, 243, 240, 0.42); /* onChromeFaint         0x6B */

  --accent: #4ade9e; /* SleeveChrome.success */
  --accent-ink: #10281d; /* onSuccess — text ON the mint fill */
  --accent-soft: rgba(74, 222, 158, 0.12);
  --caution: #e9b949; /* a caution that is not a failure */

  /* Three radii and no others, same as the app's chrome, plus the tile. */
  --r-panel: 18px;
  --r-chip: 8px;
  --r-pill: 999px;
  --r-tile: 12px;

  --page: 1064px;
  --gutter: 24px;

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --display: "Sora", var(--sans);
  --hand: "Caveat", "Segoe Script", cursive;

  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The two mint sweeps from the comp, as gradients rather than artwork: one
 * arcing in from the left behind the hero, one low on the right. Fixed, so they
 * behave as atmosphere rather than as objects that scroll past. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(
      60rem 46rem at -18% 26%,
      rgba(74, 222, 158, 0.16),
      rgba(74, 222, 158, 0) 62%
    ),
    radial-gradient(
      46rem 34rem at 112% 8%,
      rgba(74, 222, 158, 0.1),
      rgba(74, 222, 158, 0) 60%
    );
}

a {
  color: var(--accent);
  text-underline-offset: 2px;
}

a:hover {
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-chip);
}

img {
  max-width: 100%;
  height: auto;
}

h1,
h2,
h3 {
  font-family: var(--display);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
}

/* The small letterspaced caps above every section heading. */
.eyebrow {
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ------------------------------------------------------------------ chrome */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  max-width: var(--page);
  margin: 0 auto;
  padding: 20px var(--gutter);
}

.brand {
  display: block;
  line-height: 0;
}

.brand img {
  width: 92px;
  height: auto;
}

.topnav {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
}

/* 44px minimum hit target — the easiest place on a site to lose one. */
.topnav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  color: var(--ink-2);
  text-decoration: none;
}

.topnav a:hover {
  color: var(--ink);
  background: var(--panel);
}

.foot {
  border-top: 1px solid var(--hairline);
  margin-top: 80px;
}

.foot-inner {
  display: flex;
  align-items: flex-start;
  gap: 28px;
  max-width: var(--page);
  margin: 0 auto;
  padding: 28px var(--gutter) 56px;
}

.foot .brand img {
  width: 78px;
}

/* Not the faintest ink: this is constraint #9's not-affiliated claim, which has
 * to be *visible*. At onChromeFaint it measures about 3.6:1 here, under the
 * 4.5:1 floor for body text; onChromeMuted is 7:1 and still subordinate. */
.foot .notice {
  flex: 1;
  margin: 0;
  max-width: 640px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-3);
}

.foot .footlinks {
  display: flex;
  gap: 4px;
  margin: 0;
  font-size: 14px;
}

.foot .footlinks a {
  display: inline-block;
  padding: 6px 8px;
  color: var(--ink-2);
  text-decoration: none;
}

.foot .footlinks a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* ----------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 24px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.btn svg {
  flex: none;
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn-ghost {
  border-color: var(--hairline-strong);
  color: var(--ink);
}

.btn-ghost:hover {
  background: var(--panel);
}

/* Nothing is released, so nothing may look clickable. The shapes stay so the
 * page reads as designed; the fill does not. Rendered as <span>, not <a> —
 * there is no listing to link to (release-checklist M1 and M4). */
.btn.is-soon {
  cursor: default;
  border-color: var(--hairline);
  background: transparent;
  color: var(--ink-3);
}

.btn-primary.is-soon {
  background: var(--accent-soft);
  border-color: rgba(74, 222, 158, 0.3);
  color: var(--accent);
}

.soon-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border: 1px solid rgba(233, 185, 73, 0.4);
  border-radius: var(--r-pill);
  color: var(--caution);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.soon-chip .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* -------------------------------------------------------------------- hero */

.hero {
  display: grid;
  /* The comp's split at 1440: a 518px copy column and the phone at 300, which
   * is what lets "Point at the code" stay on one line. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  align-items: center;
  gap: 48px;
  max-width: var(--page);
  margin: 0 auto;
  padding: 40px var(--gutter) 8px;
}

.hero h1 {
  font-size: 58px;
  font-weight: 700;
  margin: 0 0 18px;
}

.hero h1 em {
  font-style: normal;
  color: var(--accent);
}

.hero .lede {
  max-width: 30em;
  margin: 0 0 28px;
  font-size: 17px;
  color: var(--ink-2);
  text-wrap: pretty;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.cta-state {
  margin: 0 0 14px;
}

.micro {
  margin: 0;
  font-size: 13px;
  color: var(--ink-4);
}

/* An empty slot that reads as a slot: a QR glyph and nothing else. A block of
 * fake modules would look like a code someone could point a phone at, and one
 * that scans to nothing is worse than a visible gap. Quiet, like the games
 * slot — it is a placeholder, not an offer. */
.qr-cta {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 14px;
}

/* Holds the App Store QR. White, and deliberately so: a QR needs dark modules
 * on a light ground to scan at all, and the first version of this shipped
 * black-on-transparent into a dark tile — invisible, and unreadable even where
 * you could see it. The white comes from the SVG itself so the asset is
 * correct anywhere; this just stops the tile fighting it. */
.qr {
  display: grid;
  place-items: center;
  flex: none;
  width: 62px;
  height: 62px;
  padding: 5px;
  background: #fff;
  border-radius: var(--r-tile);
  color: var(--ink-4);
}

.qr img {
  display: block;
  width: 100%;
  height: 100%;
}

.qr-text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-3);
}

.qr-note {
  color: var(--ink-4);
}

.band .note strong {
  color: var(--ink);
  font-weight: 600;
}

.tagline {
  margin: 40px 0 0;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.8;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.hero-shot {
  position: relative;
  justify-self: end;
}

.hero-shot img {
  display: block;
  width: 100%;
  max-width: 300px;
  /* The stand-in carries no baked shadow; the real export will, and this line
   * comes out then. */
  filter: drop-shadow(0 30px 60px rgba(0, 0, 0, 0.6));
}

/* "Real cards. Real results." — the one handwritten thing on the site.
 *
 * Static by default and only floated beside the phone where there is genuinely
 * room for it. The comp places it to the right of the phone, which works at
 * 1440 and is clipped by the body's overflow guard at anything narrower: the
 * phone already sits at the right edge of the content column, so the note has
 * nowhere to go. Below 1360 it drops under the phone instead. */
.scribble {
  margin: 18px 0 0;
  font-family: var(--hand);
  font-size: 21px;
  line-height: 1.25;
  text-align: center;
  color: var(--ink-2);
  pointer-events: none;
}

.scribble svg {
  display: none;
  color: var(--ink-4);
}

@media (min-width: 1360px) {
  .scribble {
    position: absolute;
    top: 4%;
    left: 100%;
    width: 9em;
    margin: 0 0 0 10px;
    text-align: left;
    transform: rotate(-6deg);
  }

  .scribble svg {
    display: block;
    margin: 4px 0 0 -4px;
  }
}

/* ------------------------------------------------------------------ bands */

.band {
  max-width: var(--page);
  margin: 0 auto;
  padding: 72px var(--gutter) 0;
}

.band > .eyebrow,
.band > h2 {
  text-align: center;
}

.band > h2 {
  margin: 0 0 28px;
  font-size: 32px;
  font-weight: 600;
}

.cards {
  display: grid;
  gap: 16px;
}

.cards.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.cards.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.card {
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  padding: 22px;
}

.card h3 {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card p {
  margin: 0;
  font-size: 15px;
  color: var(--ink-2);
  text-wrap: pretty;
}

.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}

.num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 26px;
  padding: 0 8px;
  border-radius: var(--r-chip);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.card-head svg {
  color: var(--accent);
}

/* A rounded tile behind an icon, as in the comp's second and fifth sections. */
.icon-tile {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-tile);
  background: var(--tile);
  border: 1px solid var(--hairline);
  color: var(--ink-2);
}

.card.split {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

/* ------------------------------------------------------------------ games */

.games {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.game {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  font-size: 15px;
  font-weight: 500;
}

/* PLACEHOLDER. The comp puts each publisher's logo and character art here;
 * that artwork is theirs, so until there is permission the tile carries
 * Sleeve's own mark and no colour that evokes a brand. See site/README.md. */
.emblem {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: var(--tile);
  color: var(--ink-4);
}

/* The fourth slot: a full-width strip under the three real tiles rather than a
 * lone card stranded on a second row.
 *
 * Deliberately quieter than a tile, not louder. It was mint on a mint tint at
 * first and that made a roadmap line the brightest thing in the section, ahead
 * of the games that actually work. Dashed and muted reads as an empty slot,
 * which is what it is. */
.game-more {
  grid-column: 1 / -1;
  justify-content: center;
  gap: 10px;
  padding: 12px 18px;
  background: transparent;
  border-style: dashed;
  color: var(--ink-3);
}

.game-more .emblem {
  width: 28px;
  height: 28px;
}

.band .note {
  margin: 18px 0 0;
  text-align: center;
  font-size: 14px;
  color: var(--ink-4);
}

/* ------------------------------------------------------------- honest part */

/* Sits inside `.wrap`, which owns the page width and the gutter. */
.honest {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 28px;
  margin: 72px 0 0;
  padding: 32px;
  position: relative;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
}

/* The comp's mint sweep in the panel's bottom-right. */
.honest::after {
  content: "";
  position: absolute;
  right: -12%;
  bottom: -60%;
  width: 60%;
  height: 160%;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    rgba(74, 222, 158, 0.16),
    rgba(74, 222, 158, 0) 100%
  );
  pointer-events: none;
}

.honest > * {
  position: relative;
}

.honest .icon-tile {
  width: 60px;
  height: 60px;
  border-radius: 16px;
  color: var(--accent);
}

.honest h3 {
  margin: 0 0 10px;
  font-size: 22px;
  font-weight: 600;
}

.honest p {
  margin: 0;
  max-width: 58ch;
  font-size: 15px;
  color: var(--ink-2);
  text-wrap: pretty;
}

.honest aside {
  padding-left: 28px;
  border-left: 1px solid var(--hairline);
  font-size: 11px;
  font-weight: 500;
  line-height: 2;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-4);
  white-space: nowrap;
}

/* -------------------------------------------------------- legal documents */

.doc {
  max-width: 680px;
  margin: 0 auto;
  padding: 24px var(--gutter) 0;
}

.doc h1 {
  margin: 12px 0 8px;
  font-size: 34px;
  font-weight: 600;
}

.doc section {
  margin-bottom: 32px;
}

.doc h2 {
  margin: 0 0 10px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.doc p {
  margin: 0 0 14px;
  color: var(--ink-2);
  text-wrap: pretty;
}

.doc p:last-child {
  margin-bottom: 0;
}

/* ------------------------------------------------------------ small screens */

@media (max-width: 1000px) {
  .hero {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 36px;
    padding-top: 24px;
  }

  .hero .lede {
    margin-left: auto;
    margin-right: auto;
  }

  .cta-row {
    justify-content: center;
  }

  .hero-shot {
    justify-self: center;
  }

  /* Pointless on a phone or tablet: the reader is already holding the device
   * the app installs on. */
  .qr-cta {
    display: none;
  }

  .honest {
    grid-template-columns: 1fr;
  }

  .honest aside {
    padding: 18px 0 0;
    border-left: 0;
    border-top: 1px solid var(--hairline);
    white-space: normal;
  }
}

@media (max-width: 760px) {
  :root {
    --gutter: 20px;
  }

  .cards.three,
  .cards.two,
  .games {
    grid-template-columns: 1fr;
  }

  /* 38px put "Point at the code" at exactly the content width on a 390px
   * screen — no margin at all, so a fallback face or a longer headline would
   * overflow. */
  .hero h1 {
    font-size: 34px;
  }

  /* The header's third item has nowhere to go on a phone, and the hero carries
   * the same two calls to action a screen below it. */
  .topnav .btn {
    display: none;
  }

  .band > h2 {
    font-size: 26px;
  }

  .band {
    padding-top: 56px;
  }

  /* Full-width, stacked, and each still 48px tall. */
  .cta-row {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    max-width: 320px;
    margin-inline: auto;
  }

  .foot-inner {
    flex-direction: column;
    gap: 16px;
  }

  .honest {
    padding: 24px;
  }

  .doc h1 {
    font-size: 27px;
  }
}
