/*
 * go.bonding-tunes.com: the one stylesheet every page shares.
 *
 * The app's look, carried over by value: a black floor, white ink at four
 * strengths, one accent that is always a gradient, and a pill for anything
 * pressable. The custom properties are named after the AppColors tokens in
 * lib/constants/colors.dart. When the app's palette moves, these names are
 * where to look.
 *
 * System fonts only. The app's Google Sans Flex would be a download on the
 * one page someone opens on a party's shared wifi, and every request this
 * site makes goes into the request log the privacy page describes.
 */

:root {
  color-scheme: dark;

  /* AppColors.sBackdrop: pure black, the floor of every screen. */
  --backdrop: #000;

  /* sInk100..400: white at 1, .82, .56 and .38. Body text is .82 here, a step
     down from the app's default, because a web page is mostly sentences and
     the app is mostly labels. Headings and codes take the full white. */
  --ink-100: #fff;
  --ink-200: rgba(255, 255, 255, 0.82);
  --ink-300: rgba(255, 255, 255, 0.56);
  --ink-400: rgba(255, 255, 255, 0.38);

  /* sSurface100 and sBorder100: a raised surface on black. It's a lighter
     grey plus a hairline, because a translucent black recess has no edge on
     black. */
  --surface-100: rgb(28, 28, 28);
  --border-100: rgba(255, 255, 255, 0.12);

  /* AppColors.sAccentFrom and sAccentTo, as they stand in the app today:
     sPurple600 into sBlue500. Always the pair, always in this order along the
     long axis, never one of them alone. (The pair was sViolet500
     rgb(139, 92, 246) into sAzure500 rgb(56, 165, 240) until the app
     repointed the tokens. If it points back, change these two lines.) */
  --accent-from: rgb(152, 71, 209);
  --accent-to: rgb(0, 170, 255);
  --accent: linear-gradient(90deg, var(--accent-from), var(--accent-to));

  /* "A press lifts with white, never darkens", as in the app. */
  --lift: rgba(255, 255, 255, 0.08);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    "Noto Sans", sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Anything that sets its own display (every .button is flex) would otherwise
   beat the browser's own [hidden] rule, and the hidden App Store button
   would show up empty. */
[hidden] {
  display: none !important;
}

/* The black goes on html, not body. The glow below is body's child at
   z-index -1, and it paints behind body's own background if body has one. */
html {
  background: var(--backdrop);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  color: var(--ink-200);
  font-family: var(--font);
  font-size: 1.125rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The home screen's bottom glow (SBottomGlow in
   lib/ui_components/layouts/bottom_glow.dart). It's the one picture these
   pages have, and it sits where the app puts it.

   Two sweeps, each hot in a bottom corner: the blue from the left and the
   purple from the right, leaning towards each other on the way up. Each peaks
   at .4 alpha and is gone well before the top, so the band's top edge stays
   genuinely black. The band is 42% of the screen tall, capped at 400px, so on
   a tablet it still reads as light coming from somewhere.

   The angles and the 54% stop reproduce the app's geometry for a
   phone-shaped band. There, each axis ends a quarter of the way in from its
   own side, and the ramp is spent 65% of the way along it. A wider band gets
   a slightly different lean. For a glow that's fine, and it keeps CSS
   trigonometry out of the stylesheet. */
body::before {
  content: "";
  position: fixed;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: 0;
  height: min(42vh, 400px);
  pointer-events: none;
  background:
    linear-gradient(15deg, rgba(0, 170, 255, 0.4), rgba(0, 170, 255, 0) 54%),
    linear-gradient(-15deg, rgba(152, 71, 209, 0.4), rgba(152, 71, 209, 0) 54%);
  /* On a wide screen the same angles hit the band's top edge before they
     reach zero, which draws a hard horizontal line across the page. Fading
     the band's top half removes the edge at any width, and on a phone it
     costs almost nothing, since the sweeps are already spent up there. */
  -webkit-mask-image: linear-gradient(to top, #000 45%, transparent);
  mask-image: linear-gradient(to top, #000 45%, transparent);
}

/* One column, sized for a phone, and centred on anything wider. The safe-area
   insets keep the wordmark out from under a notch in landscape (the viewport
   meta asks for viewport-fit=cover). */
.page {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 30rem;
  min-height: 100vh;
  min-height: 100svh;
  margin: 0 auto;
  padding: max(1.25rem, env(safe-area-inset-top)) max(1.5rem, env(safe-area-inset-right))
    max(1.5rem, env(safe-area-inset-bottom)) max(1.5rem, env(safe-area-inset-left));
}

/* The app's wordmark is set as type, not as a drawn logo, and so is this one:
   STitle40 is 800 weight in white. */
.top {
  text-align: center;
}

.wordmark {
  color: var(--ink-100);
  font-size: 1.75rem;
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.stage {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  padding: 3rem 0 2rem;
  text-align: center;
}

.codeblock {
  margin-bottom: 1.75rem;
}

.eyebrow {
  margin: 0 0 0.5rem;
  color: var(--ink-300);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* The code: a card's NL·O·42, a box's NL·O, a room's ABCDE. It's the biggest
   thing on the page, because it's what the reader matches against the card
   in their hand or the code on the host's phone. */
.code {
  margin: 0;
  color: var(--ink-100);
  font-size: clamp(3rem, 15vw, 4.75rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* A room code is five letters and nothing else. It gets the lobby's wider
   tracking, so it reads one letter at a time, the way it's read aloud. */
.code--room {
  font-size: clamp(3rem, 16vw, 5rem);
  letter-spacing: 0.08em;
}

/* A card from an edition with a region tag (PT-BR·O·1234) has twice the
   usual characters. site.js marks such a code so it steps down a size,
   instead of breaking at its hyphen. */
.code--long {
  font-size: clamp(2.25rem, 10vw, 3.5rem);
}

.nowrap {
  white-space: nowrap;
}

/* The code as the accent gradient, like the lobby's code on the host's
   phone. It goes on the inner span, not the paragraph. An inline span is as
   wide as its text, so the sweep runs from the first character to the last
   instead of across the whole column. Gated, because without background-clip
   the transparent fill would leave the code invisible. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .code > [aria-hidden="true"] {
    background-image: var(--accent);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

/* The page's one sentence. It's an h1 because it's what the page is for,
   even though the code above it is set larger. */
.lead {
  max-width: 22em;
  margin: 0 auto;
  color: var(--ink-200);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.45;
  text-wrap: balance;
}

.lead--large {
  color: var(--ink-100);
  font-size: clamp(1.625rem, 7vw, 2.125rem);
  font-weight: 800;
  line-height: 1.25;
}

.actions,
.stores {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.actions {
  margin-top: 2.5rem;
}

/* SLargeButton: a pill (kRadiusLarge) at least 54px tall (kMinHeightLarge),
   with a 19px bold label. */
.button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 3.375rem;
  padding: 0.625rem 1.5rem;
  border-radius: 999px;
  color: var(--ink-100);
  font-size: 1.1875rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

/* The one committed action on a page ("Open in the app"). It's the accent
   fill, upper-cased like the app's primary button, and at most one per page.
   The store buttons are the quiet ones. */
.button--primary {
  background-image: var(--accent);
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.store {
  border: 1px solid var(--border-100);
  background-color: var(--surface-100);
}

.store small {
  display: block;
  color: var(--ink-300);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.store strong {
  display: block;
  color: var(--ink-100);
  font-size: 1.125rem;
  font-weight: 700;
}

/* A press lifts with white. An inset shadow rather than a second background
   works on the gradient fill as well as the flat one. */
.button:active {
  box-shadow: inset 0 0 0 999px var(--lift);
}

@media (hover: hover) {
  .button:hover {
    box-shadow: inset 0 0 0 999px var(--lift);
  }
}

a:focus-visible {
  outline: 2px solid var(--ink-100);
  outline-offset: 3px;
}

.foot {
  padding-top: 1rem;
  color: var(--ink-400);
  font-size: 0.875rem;
  text-align: center;
}

.foot a {
  color: var(--ink-300);
  text-decoration: none;
}

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

/* The privacy page: running text, left-aligned, same column. */
.prose {
  flex: 1;
  padding: 2.5rem 0 2rem;
}

.prose h1 {
  margin: 0 0 0.5rem;
  color: var(--ink-100);
  font-size: 2rem;
  font-weight: 800;
  line-height: 1.2;
}

.prose h2 {
  margin: 2rem 0 0.5rem;
  color: var(--ink-100);
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.3;
}

.prose p {
  margin: 0 0 1rem;
}

.prose .meta {
  margin-bottom: 2rem;
  color: var(--ink-300);
  font-size: 0.9375rem;
}

.prose a {
  color: var(--ink-100);
  text-decoration-color: var(--ink-400);
  text-underline-offset: 0.15em;
}

/* For screen readers only: the spoken form of a code (see showCode in
   site.js). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
