/*
 * gridticker.com. The brand's own colours (docs/BRAND.md), and deliberately
 * SYSTEM fonts: the site loads nothing from anyone else, which is what lets
 * its own privacy policy say so. Barlow Condensed, the wordmark's face, is
 * used where a visitor happens to have it and falls back to a condensed
 * system face where they do not.
 */
:root {
  --bg: #050709;
  --surface: #0f1419;
  --border: #1a2530;
  --text: #dfeaf5;
  --muted: #9ab8d5;
  --red: #ff2d2d;
  /* A fill under white text: 5.05:1, where white on --red is 3.71:1. The
     app's --color-jq-red-fill. */
  --red-fill: #d91e1e;
  --amber: #ffb800;
  --display: "Barlow Condensed", "Avenir Next Condensed", "Arial Narrow", "Roboto Condensed",
    sans-serif;
  --body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.6 var(--body);
}

a {
  color: var(--text);
  text-decoration-color: var(--red);
  text-underline-offset: 3px;
}
a:hover {
  color: var(--red);
}

.top,
main,
.bottom {
  max-width: 760px;
  margin: 0 auto;
  padding: 0 20px;
}

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 20px;
  padding-bottom: 20px;
}

/* The mark is the G of GRIDTICKER, set as a capital: it stands on the word's
   baseline and the word is sized so its capitals are the tile's height, less a
   hair - the app's lockup (dashboard/src/components/Logo.tsx), in one number. */
.lockup {
  --logo-size: 24px;
  display: inline-flex;
  align-items: baseline;
  gap: calc(var(--logo-size) * 0.07);
  text-decoration: none;
  font: 700 calc(var(--logo-size) * 0.96 / 0.7) / 1 var(--display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.lockup img {
  display: block;
  width: var(--logo-size);
  height: var(--logo-size);
}

.top-actions {
  display: inline-flex;
  align-items: center;
  gap: 18px;
}
.signin {
  font-weight: 600;
}
/* The way IN, beside the way back. A button rather than a third link, because
   the header's job on a marketing page is to make one of the two obvious.

   --red-fill, not --red: white on the fill is 5.05:1 and on --red it is
   3.71:1, which the palette above says in so many words. Matches .btn-primary,
   so the header and the hero are one button rather than two that nearly
   agree. */
.top-cta {
  font-weight: 700;
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--red-fill);
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}
.top-cta:hover {
  background: var(--red);
  color: #fff;
}
.cta-fine {
  margin-top: -4px;
  font-size: 14px;
  opacity: 0.72;
}
.join-title {
  margin-top: 36px;
  font-size: 18px;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.15;
}
h1 {
  font-size: 40px;
  margin: 24px 0 12px;
}
h2 {
  font-size: 26px;
  margin: 36px 0 8px;
}
h3 {
  font-size: 20px;
  margin: 24px 0 4px;
}

p,
li {
  max-width: 68ch;
}

.lede {
  font-size: 19px;
  color: var(--muted);
}

.updated {
  color: var(--muted);
  font-size: 14px;
}

/* The two notices a visitor must not miss. */
.soon,
.draft {
  border-radius: 6px;
  padding: 12px 16px;
  margin: 8px 0 20px;
}
.soon {
  background: var(--red-fill);
  color: #fff;
  font-weight: 700;
}
.draft {
  border: 1px solid var(--amber);
  color: var(--amber);
}
mark.todo {
  background: var(--amber);
  color: #000;
  padding: 0 4px;
  border-radius: 3px;
}

.strip {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  border-radius: 4px;
  border: 1px solid var(--border);
  margin: 12px 0 4px;
}
.caption {
  color: var(--muted);
  font-size: 14px;
  margin-top: 0;
}

.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  padding: 0;
  list-style: none;
}
.features li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 14px 16px;
}
.features b {
  display: block;
  font: 700 20px/1.2 var(--display);
  letter-spacing: 0.02em;
  margin-bottom: 4px;
}

table {
  border-collapse: collapse;
  width: 100%;
  margin: 12px 0;
  font-size: 15px;
}
th,
td {
  text-align: left;
  vertical-align: top;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
th {
  color: var(--muted);
  font-weight: 600;
}
/* A table must not push the page sideways on a phone: it scrolls in its own box. */
.table-wrap {
  overflow-x: auto;
}

code,
kbd {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 5px;
}

.bottom {
  margin-top: 56px;
  padding-top: 20px;
  padding-bottom: 40px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 14px;
}
.bottom nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin-bottom: 10px;
}
.bottom a[aria-current="page"] {
  color: var(--red);
}
.fine {
  font-size: 13px;
}

@media (max-width: 480px) {
  h1 {
    font-size: 32px;
  }
  .lockup {
    --logo-size: 20px;
  }
}


/* ==========================================================================
   The front page (body.home)
   --------------------------------------------------------------------------
   A control room after dark: near-black, hairline rules, one red, and the
   ticker itself as the thing on the wall. No JavaScript - the site's CSP
   refuses it - so every bit of movement here is CSS, and every bit of depth
   is a gradient or a shadow rather than an image somebody has to download.
   ========================================================================== */

body.home main {
  max-width: 1080px;
  padding-inline: 24px;
}

body.home .top,
body.home .bottom {
  max-width: 1080px;
  padding-inline: 24px;
}

/* The page's own light source: one soft red bloom behind the hero, and the
   scanlines a bright strip throws on a dark wall. Both are drawn, not
   loaded. */
body.home {
  background:
    radial-gradient(60rem 28rem at 50% -8rem, rgba(255, 45, 45, 0.14), transparent 70%),
    repeating-linear-gradient(
      to bottom,
      rgba(255, 255, 255, 0.016) 0 1px,
      transparent 1px 3px
    ),
    var(--bg);
}

.hero {
  padding: clamp(2.5rem, 7vw, 6rem) 0 clamp(1.5rem, 3vw, 2.5rem);
  text-align: center;
}

/* `text-align: center` centres the TEXT inside each box; it does not centre
   the boxes. Every paragraph here is capped at 68ch by the `p, li` rule far
   above, so without this the eyebrow, the button row and the fine print sit
   flush left inside a measure narrower than the hero - while h1 and .lede,
   which each set `margin: … auto` of their own, sat centred. Three elements
   were off by 145-205px and it read as a layout bug rather than a rule. */
.hero > * {
  margin-inline: auto;
}

.eyebrow {
  /* `auto`, not 0: this shorthand sets the inline margins too, and being the
     later rule of equal specificity it beat `.hero > *` above - which is why
     this line stayed 205px left of everything else after that rule landed. */
  margin: 0 auto 1.25rem;
  font: 600 0.78rem/1 var(--body);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--muted);
}

.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 0.6em;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 3px rgba(255, 45, 45, 0.18);
  vertical-align: 1px;
}

.hero h1 {
  margin: 0 auto;
  max-width: 14ch;
  font: 700 clamp(2.9rem, 8.5vw, 6.2rem) / 0.92 var(--display);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}

.hero .lede {
  margin: 1.4rem auto 0;
  max-width: 54ch;
  font-size: 1.12rem;
  color: var(--muted);
}

.cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: 2rem;
}

.btn {
  display: inline-block;
  padding: 0.85em 1.6em;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: transparent;
  color: var(--text);
  font: 600 0.95rem/1 var(--body);
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}

.btn:hover {
  color: var(--text);
  border-color: var(--muted);
  transform: translateY(-1px);
}

.btn-primary {
  background: var(--red-fill);
  border-color: var(--red-fill);
  color: #fff;
}

.btn-primary:hover {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

/* ---------- the panel the ticker sits in ---------- */

.panel-wrap {
  margin: clamp(1.5rem, 4vw, 3rem) 0 clamp(2rem, 5vw, 3.5rem);
  scroll-margin-top: 2rem;
}

/* A bezel, not a border: the strip is a physical object, and a couple of
   millimetres of dark plastic around it is what says so. The inner shadow is
   the glass; the outer one is the wall behind it. */
.panel {
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: linear-gradient(180deg, #11181f, #070b0f);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 30px 80px -40px rgba(255, 45, 45, 0.45),
    0 20px 60px -30px rgba(0, 0, 0, 0.9);
}

/* Tall, because the demo is STACKED: one row per feed - games, flights, news,
   stocks - each scrolling on its own. A short frame would show the sports row
   and hide the product. The rows size themselves to the height they are
   given, so this is the one number that decides how much of it is on screen. */
/* `--fs` inside the demo is the row's own height times 0.3, so this box does
   not merely crop the ticker - it SIZES it, and for a day this height was a
   media query shortening the frame to 150px on a phone to stop the type
   reaching 96px.
   That was treating the symptom in the wrong file. The type is capped by
   WIDTH now (TickerStrip's apply), so a 305x320 frame on a phone stacks into
   four rows at 26px - measured - and the shortened frame only stopped it
   stacking at all. One clamp again. */
.demo-strip {
  display: block;
  width: 100%;
  height: clamp(320px, 38vw, 520px);
  border: 0;
  border-radius: 6px;
  background: #000;
}

.demo-tall {
  height: clamp(380px, 46vw, 640px);
}

.panel-note {
  margin: 0.9rem 2px 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ---------- the league marquee ---------- */

.marquee {
  overflow: hidden;
  margin: 0 0 clamp(2.5rem, 6vw, 4.5rem);
  padding: 0.85rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  /* Fades at both ends, so the loop has no visible seam. */
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee-track {
  display: flex;
  width: max-content;
  gap: 2.6rem;
  animation: slide 46s linear infinite;
}

.marquee-track span {
  font: 600 0.82rem/1 var(--body);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #6f8299;
  white-space: nowrap;
}

@keyframes slide {
  from { transform: translateX(0); }
  /* The list is written twice; half a loop is a whole one. */
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

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

.band {
  padding: clamp(2rem, 5vw, 4rem) 0;
  border-top: 1px solid var(--border);
}

.band-title {
  margin: 0 0 1.75rem;
  font: 700 clamp(1.5rem, 3.4vw, 2.3rem) / 1.05 var(--display);
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.cards {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

/* One hairline grid, drawn by the gaps: the cards are opaque tiles over a
   border-coloured background, so every rule is exactly one pixel and none of
   them double up at a corner. */
.card {
  padding: 1.6rem;
  background: var(--bg);
  transition: background 0.18s ease;
}

.card:hover {
  background: var(--surface);
}

.card h3 {
  margin: 0 0 0.6rem;
  font: 700 1.12rem/1.2 var(--display);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.97rem;
}

.band-split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  align-items: start;
}

.split-text p {
  color: var(--muted);
  max-width: 46ch;
}

.steps {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.steps li {
  position: relative;
  counter-increment: step;
  padding: 1.1rem 0 1.1rem 3.6rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
}

.steps li:last-child {
  border-bottom: 1px solid var(--border);
}

.steps li b {
  color: var(--text);
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.75rem;
  font: 700 1.9rem/1 var(--display);
  color: var(--red);
}

.band-quiet .strip {
  margin: 0 0 1.25rem;
}

.band-quiet p {
  color: var(--muted);
  max-width: 60ch;
}

.closing {
  text-align: center;
  padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
}

.closing p {
  margin: 0 auto;
  max-width: 52ch;
  color: var(--muted);
}

.closing b {
  color: var(--text);
}

/* The "not open yet" note is the first thing on the page and should read as a
   line of type, not as an error. */
body.home .soon {
  margin: 1.25rem 0 0;
  padding: 0;
  border: 0;
  background: none;
  text-align: center;
  font-size: 0.86rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}

@media (max-width: 40rem) {
  .hero h1 { max-width: 18ch; }
  .card { padding: 1.3rem; }
}


.band-lede {
  margin: -0.75rem 0 1.5rem;
  max-width: 52ch;
  color: var(--muted);
}

/* ---------- the launch list ---------- */

.join {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: center;
  margin: 1.75rem auto 0.9rem;
  max-width: 34rem;
}

/* The label is for a screen reader and for anybody who has turned CSS off; the
   placeholder is not a label and never was. */
.join-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.join-input {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.85em 1em;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  font: 400 1rem/1 var(--body);
}

.join-input::placeholder {
  color: #5d7086;
}

.join-input:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
  border-color: var(--red);
}

.closing .fine {
  margin: 0 auto;
  max-width: 44ch;
  font-size: 0.82rem;
  color: #7f93a8;
}
