/*
 * CompyDeadlock.com — Deadlock's UI language, approximated with web-safe faces.
 *
 * WHERE THIS PALETTE COMES FROM. It is not invented here, and it is not owned
 * here either: this file and `apps/coach/src/styles/tokens.css` MOVE TOGETHER,
 * always, because the desktop app, the web build, this site and the YouTube
 * channel are one product. That file carries the full reasoning and every
 * measured contrast ratio; this header carries the summary and the
 * site-specific consequences.
 *
 * 2026-08-19 (`task.product-restyle-navy-gold-purple`, owner call) REPLACED the
 * warm cream-on-brown-black palette with a DEEP NAVY ground and TWO accents:
 * gold `#d9a441` (unchanged hex) now means COMPARISON — the cohort, the
 * baseline, the pros — and purple `#a78bfa` means YOU, the player being
 * analysed. This page has no such data on it, so it spends gold exactly as it
 * always did (the rule, the eyebrow, the one large fill) and carries the purple
 * only as tokens, so the builds bundle rendered into `builds.html` — which is
 * the coach app and DOES have that data — inherits one palette rather than two.
 *
 * The GEOMETRY is untouched and still comes from
 * `apps/coach/scripts/montage/overlayCard.ts`: generous uppercase tracking on
 * supporting type, and a CLIPPED top-right corner rather than a rounded one —
 * Deadlock's deco framing reads as a cut corner, and a border-radius
 * immediately reads as a web chip instead. The montage overlays and this site
 * therefore still look like the same project, which is the point: the channel
 * is the front door and this page is where that traffic lands.
 *
 * NO WEB FONTS, for the same reason overlayCard.ts gives: a font that fails to
 * download silently changes the whole render. Georgia for display, Trebuchet MS
 * for supporting type, both with real fallbacks. It also means zero
 * render-blocking network requests and no FOUT layout shift, which is what
 * `task.web-landing-page` asks for on mobile.
 *
 * Shared by the landing page, the per-hero builds page and the unlisted
 * download page, so the download page inherits the theme for free.
 */

:root {
  color-scheme: dark;

  /* Core palette — mirrors apps/coach/src/styles/tokens.css exactly. */
  --ink: #e9edf7;          /* cool off-white, the body text colour: 16.46:1 on --bg */
  --ink-dim: rgba(233, 237, 247, 0.62);
  --ink-faint: rgba(233, 237, 247, 0.38);
  --gold: #d9a441;         /* accent one — CHROME, and COMPARISON in the data */
  --gold-soft: rgba(217, 164, 65, 0.26);
  --gold-faint: rgba(217, 164, 65, 0.12);
  --purple: #a78bfa;       /* accent two — YOU, the player under analysis */
  --purple-soft: rgba(167, 139, 250, 0.26);
  --purple-faint: rgba(167, 139, 250, 0.12);

  /* The semantic pair. Named for the MEANING so nothing downstream hardcodes a
     hue; the same two names exist in the app's tokens.css. */
  --you: var(--purple);
  --cohort: var(--gold);

  /* Navy darks. The base is a blue-black, not #111 and no longer the old
     brown-black — a near-neutral-COOL ground lets both accents sit off it at
     full saturation instead of sharing the ground's own hue. */
  --bg: #0a0e18;
  --bg-2: #111726;
  --panel: #151c2e;
  --panel-hi: #1d2639;

  --danger-bg: #2b2410;
  --danger-border: #7a5c14;
  --danger-ink: #f0d78c;

  --code-bg: #05070d;

  --deco-cut: 22px;        /* the clipped-corner size, shared so it stays consistent */
  --serif: Georgia, "Times New Roman", "Nimbus Roman", serif;
  --sans: "Trebuchet MS", "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  min-height: 100vh;
  /* A faint gold vignette so the page is not a flat slab — kept gold rather
     than moved to the purple, because it is CHROME and the purple is reserved
     for data. Pure CSS: no image request, so it cannot shift layout or fail to
     load. */
  background-image:
    radial-gradient(1100px 520px at 50% -10%, rgba(217, 164, 65, 0.10), transparent 70%),
    linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 42%);
  background-repeat: no-repeat;
}

a { color: var(--gold); }
a:hover { color: #f0bf62; }

.wrap {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

.narrow { max-width: 760px; }

/* ─── deco primitives ──────────────────────────────────────────────────────
   The clipped top-right corner plus a 6px gold left border IS the visual
   signature. Everything that wants to look like a Deadlock panel uses these
   two classes rather than restating the geometry. */

.cut {
  clip-path: polygon(
    0 0,
    calc(100% - var(--deco-cut)) 0,
    100% var(--deco-cut),
    100% 100%,
    0 100%);
}

.panel {
  background: linear-gradient(100deg, var(--panel-hi) 0%, var(--panel) 100%);
  border-left: 6px solid var(--gold);
  padding: 1.35rem 1.5rem;
  box-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

/* ─── type ─────────────────────────────────────────────────────────────── */

h1, h2, h3 { font-family: var(--serif); font-weight: 700; margin: 0; }

h1 {
  font-size: clamp(2.4rem, 7vw, 4.2rem);
  line-height: 1.02;
  letter-spacing: 0.005em;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.75);
}

h2 { font-size: clamp(1.5rem, 3.6vw, 2.05rem); line-height: 1.12; }
h3 { font-size: 1.1rem; line-height: 1.25; }

/* The uppercase, widely-tracked label — the single most Deadlock-looking piece
   of type in the system. Used for section eyebrows and stat captions. */
.eyebrow {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 0.5rem;
}

.lede { font-size: 1.08rem; color: var(--ink-dim); }

.rule {
  height: 1px;
  background: linear-gradient(90deg, var(--gold-soft), transparent 72%);
  border: 0;
  margin: 3.2rem 0;
}

code { font-family: var(--mono); font-size: 0.86em; background: var(--code-bg); padding: 0.1em 0.4em; }
pre {
  font-family: var(--mono);
  font-size: 0.82rem;
  background: var(--code-bg);
  border: 1px solid var(--gold-faint);
  padding: 0.9rem 1rem;
  overflow-x: auto;
}

/* ─── masthead ─────────────────────────────────────────────────────────── */

.masthead {
  border-bottom: 1px solid var(--gold-faint);
  background: rgba(10, 14, 24, 0.72);
}

.masthead .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 62px;
  flex-wrap: wrap;
}

.wordmark {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
}
.wordmark b { color: var(--gold); font-weight: 700; }

.masthead nav {
  display: flex;
  gap: 1.3rem;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}
.masthead nav a { color: var(--ink-dim); text-decoration: none; }
.masthead nav a:hover { color: var(--gold); }

/* ─── hero band ────────────────────────────────────────────────────────── */

.band { padding: clamp(3rem, 8vw, 5.5rem) 0 clamp(2rem, 5vw, 3.5rem); }

.band h1 em {
  font-style: normal;
  color: var(--gold);
}

.band .lede { max-width: 46ch; margin: 1.1rem 0 0; }

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 2rem;
}

/* Buttons are cut, not rounded, and the primary one is the only large gold
   fill on the page — which is why it is spent on the YouTube channel and not
   on a download. `task.web-landing-page`: no download button above the fold,
   and `task.web-download-unlisted`: the download is not linked from here at
   all. */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.9rem 1.5rem;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition: filter 120ms ease, background-color 120ms ease;
}

.btn-primary { background: var(--gold); color: #0a0e18; }
.btn-primary:hover { filter: brightness(1.09); color: #0a0e18; }

/* The secondary button's outline has to follow the CUT corner. An inset
   box-shadow or a plain border cannot: both are drawn on the element's
   rectangle and then sliced off by clip-path, which leaves the diagonal edge
   bare and a stray horizontal line across the notch. So the frame is the
   element's own background, and a negative-z pseudo-element paints the fill
   1px inside it with the same geometry. Negative-z descendants paint above the
   parent's background and below its text, which is exactly the stack needed. */
.btn-ghost {
  position: relative;
  isolation: isolate;
  background: var(--gold-soft);
  color: var(--ink);
}

.btn-ghost::before {
  content: '';
  position: absolute;
  inset: 1px;
  z-index: -1;
  background: #0d1220;
  clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
  transition: background-color 120ms ease;
}

.btn-ghost:hover { color: var(--ink); }
.btn-ghost:hover::before { background: #1d2639; }

/* ─── card row ─────────────────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  margin-top: 1.6rem;
}

.cards .panel p { margin: 0.5rem 0 0; color: var(--ink-dim); font-size: 0.95rem; }

/* ─── hero grid ────────────────────────────────────────────────────────── */

.grid-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.hero-grid {
  display: grid;
  /* 104px floor puts 3 tiles across a 360px phone with room for the gap, and
     lets a desktop fill out to 7-8 without a media query. */
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 0.7rem;
  margin-top: 1.5rem;
  padding: 0;
  list-style: none;
}

@media (min-width: 700px) {
  .hero-grid { grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); gap: 0.9rem; }
}

.hero-tile {
  position: relative;
  display: block;
  text-decoration: none;
  color: var(--ink);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.30) 100%),
    var(--tile-accent, #1d2639);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  overflow: hidden;
  transition: transform 130ms ease, box-shadow 130ms ease;
}

.hero-tile:hover,
.hero-tile:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.55);
  outline: none;
  color: var(--ink);
}

.hero-tile:focus-visible .hero-tile-art { box-shadow: inset 0 0 0 2px var(--gold); }

/* RESERVED BOX. The aspect-ratio is declared here and the <img> is absolutely
   positioned inside it, so the tile occupies its final size before a single
   byte of art arrives. That is what keeps CLS at zero on a grid of 38 remote,
   lazily-loaded images — the thing most likely to wreck a Lighthouse mobile
   score on this page. */
.hero-tile-art {
  position: relative;
  aspect-ratio: 280 / 340;
  overflow: hidden;
}

.hero-tile-art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 12%;
  /* Portrait art is transparent-background, so it sits ON the accent wash. */
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.5));
}

/* The graceful-degradation layer. If the upstream bucket is unavailable the
   <img> is hidden by its own onerror handler and THIS shows through: the
   hero's initial on its own accent colour. The grid stays a grid, the links
   still work, and nothing collapses. `task.web-hero-grid-entry`: "the page does
   not break if the upstream source is unavailable". */
.hero-tile-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 2.2rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
}

.hero-tile-name {
  position: relative;
  display: block;
  background: linear-gradient(180deg, rgba(7, 10, 18, 0.55), rgba(7, 10, 18, 0.92));
  padding: 0.42rem 0.55rem 0.5rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* HERO WITH NO BUILDS DATA. Not a link, and it says why. Valve ships a hero
   before we have parsed replays for it, and `task.web-hero-grid-entry` calls a
   silent link to an empty page out by name as the failure to avoid. */
.hero-tile.is-empty { cursor: default; opacity: 0.55; }
.hero-tile.is-empty:hover { transform: none; box-shadow: none; }
.hero-tile.is-empty .hero-tile-art img { filter: grayscale(1) brightness(0.8); }

.hero-tile-badge {
  position: absolute;
  top: 0;
  left: 0;
  background: rgba(6, 9, 16, 0.86);
  color: var(--gold);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.24rem 0.5rem;
}

.grid-note { color: var(--ink-faint); font-size: 0.85rem; margin-top: 1rem; }

/* ─── channel band ─────────────────────────────────────────────────────── */

.channel {
  display: grid;
  gap: 1.4rem;
  align-items: center;
}

@media (min-width: 780px) {
  .channel { grid-template-columns: 1.35fr 1fr; gap: 2.4rem; }
}

.channel .panel { padding: 1.6rem 1.8rem; }

.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  margin-top: 1.2rem;
}

.stat-row div { min-width: 0; }

.stat-num {
  font-family: var(--serif);
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
}

.stat-cap {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-top: 0.35rem;
}

/* ─── footer ───────────────────────────────────────────────────────────── */

footer {
  border-top: 1px solid var(--gold-faint);
  margin-top: 3.5rem;
  padding: 2rem 0 3rem;
  color: var(--ink-faint);
  font-size: 0.82rem;
}

footer p { margin: 0.5rem 0; max-width: 70ch; }

/* ─── the unlisted download page ───────────────────────────────────────── */

.doc { padding: 2.5rem 0 1rem; }
.doc section { margin: 1.6rem 0; }
.doc h2 { font-size: 1.25rem; margin-bottom: 0.6rem; }
.doc ul, .doc ol { padding-left: 1.2rem; margin: 0.5rem 0; }
.doc li { margin: 0.35rem 0; }

.warning {
  background: var(--danger-bg);
  border-left: 6px solid var(--danger-border);
  padding: 1.25rem 1.4rem;
}
.warning h2 { color: var(--danger-ink); }

.smartscreen-mock {
  margin: 1rem 0;
  overflow: hidden;
  border: 1px solid #3d4149;
  max-width: 420px;
}
.smartscreen-mock .titlebar { background: #0a4a90; color: #fff; font-size: 0.85rem; padding: 0.4rem 0.7rem; }
.smartscreen-mock .body { background: #f3f3f3; color: #1b1b1b; padding: 1rem 1rem 0.9rem; font-family: var(--sans); }
.smartscreen-mock .icon-row { display: flex; align-items: flex-start; gap: 0.7rem; }
.smartscreen-mock .shield { font-size: 1.6rem; line-height: 1; }
.smartscreen-mock .headline { font-weight: 600; margin: 0 0 0.25rem; }
.smartscreen-mock .sub { margin: 0; font-size: 0.85rem; color: #3a3a3a; }
.smartscreen-mock .more-info { display: inline-block; margin-top: 0.7rem; font-size: 0.85rem; color: #0a5cbf; text-decoration: underline; }
.smartscreen-mock .buttons { margin-top: 0.85rem; display: flex; gap: 0.5rem; justify-content: flex-end; }
.smartscreen-mock button { font: inherit; font-size: 0.85rem; padding: 0.35rem 0.9rem; border: 1px solid #b9b9b9; background: #e1e1e1; color: #1b1b1b; }
.smartscreen-mock button.run-anyway { background: #0067c0; border-color: #0067c0; color: #fff; font-weight: 600; }

#download-section dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1rem;
  margin: 0 0 1.1rem;
}
#download-section dt { color: var(--ink-dim); font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 600; }
#download-section dd { margin: 0; word-break: break-all; }

.download-button { font-size: 0.85rem; }
.download-button[aria-disabled="true"] { pointer-events: none; opacity: 0.5; }

#status { color: var(--ink-dim); }

#error-section { background: var(--danger-bg); border-left: 6px solid var(--danger-border); padding: 1rem 1.25rem; }
#error-section p { margin: 0.3rem 0; }

/* ─── motion ───────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .hero-tile:hover { transform: none; }
}
