/* ══════════════════════════════════════════════════════════════════════════
   ARES — ares-ad.com

   The world is Ares' own, taken from the product's DESIGN.md rather than
   invented for the marketing site: THE MEDIA PLAN, MADE LIVE. Before
   dashboards existed, an agency's central artifact was the media plan —
   channels down the left, weeks across the top, weight drawn as bars, cost
   totalled in a ledger column, APPROVED stamped in the corner.

   A product site that invents its own look teaches the visitor a language the
   app then contradicts. Every value below is the value the app ships.

   Colour is a LAW here, not decoration. The ground is BLUE-black, never
   neutral: a blue-black ground reads as a printed surface under light, where
   #000 reads as an OLED void. Process cyan is a printer's ink, not a neon, and
   it means exactly one thing — THIS IS RUNNING.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Archivo. A grotesk drawn from 19th-century American gothics: the lettering
      of newsprint and advertising, which is exactly where a media plan lived.
      Variable 100–900, subset, 18.4KB. The preload in the document must match
      this URL byte for byte or the browser fetches the face twice. */
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo.woff2?v=1') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ══ MONOCHROME ════════════════════════════════════════════════════════
     The world is black and white now. Process cyan is gone, and so is the
     blue-black ground it was chosen to sit on — a blue cast with no blue
     accent left to justify it just reads as a screen that is slightly the
     wrong colour. Neutral black, neutral greys, white.

     THE HARD PART OF MONOCHROME IS STATE. Four channel statuses used to be
     four hues; hue is the one axis a black-and-white page does not have. So
     status is carried by LUMINANCE and weight instead: the thing that is
     running is the brightest thing in the row and it glows; the thing that is
     learning sits mid-grey; the thing that is stopped is a dim outline with no
     fill. That is a real ranking a reader can scan, rather than four colours
     they have to learn.

     Every step below is measured on the ground: 19.6, 17.5, 9.5 and 5.2 to 1. */

  /* Ground and sheet — neutral, never blue */
  --bg:            #0A0B0C;
  --panel:         #131416;
  --raised:        #1B1D1F;
  --line:          #2A2C2F;
  --line-strong:   #3E4145;

  /* Ink */
  --ink:           #F4F4F3;   /* 17.5:1 */
  --mut:           #B5B7B9;   /* 9.5:1  */
  --dim:           #86898D;   /* 5.2:1 — still passes as body text */

  /* The one accent is light itself */
  --accent:        #FFFFFF;   /* 19.6:1 — means: this is running */
  --accent-hi:     #FFFFFF;
  --accent-text:   #FFFFFF;
  --glow:          0 0 22px rgba(255,255,255,.22);   /* the white bloom, rationed */

  /* Rationed states, as luminance rather than hue */
  --win:           #F4F4F3;   /* the brightest thing wins */
  --loss:          #6E7175;   /* stopped recedes */
  --warn:          #A9ACB0;   /* caution sits between them */

  /* Measure and rhythm */
  --wide:          1240px;
  --read:          68ch;
  --gutter:        clamp(20px, 5vw, 64px);

  /* One deceleration curve for the whole site. Motion that arrives rather than
     stops. Everything shares it, which is what makes separate animations read
     as one system instead of as separate effects. */
  --ease:          cubic-bezier(.22, 1, .36, 1);
  --ease-firm:     cubic-bezier(.32, .72, 0, 1);

  color-scheme: dark;
}

/* ══ RESET ═══════════════════════════════════════════════════════════════ */

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

html {
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The anchor targets sit under a fixed bar; without this every jump lands
     the heading beneath it. */
  scroll-padding-top: 88px;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: transparent;
  color: var(--ink);
  font-family: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;   /* clip, not hidden: hidden makes the root a scroll container
                         and breaks position:sticky on every section below */
}

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

/* Money and any figure that ticks. A ledger column that reflows width as it
   counts is a column nobody can read. */
.ledger, .tick { font-variant-numeric: tabular-nums lining-nums; }

.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ══ TYPE ════════════════════════════════════════════════════════════════
   Tracking is size-specific, never one value for all sizes: large display type
   reads too loose as it grows and wants negative tracking; small caps want
   positive. A single letter-spacing is wrong somewhere. */

h1, h2, h3 { font-weight: 700; line-height: 1.04; text-wrap: balance; }

h1 {
  font-size: clamp(2.6rem, 7.2vw, 5.4rem);
  letter-spacing: -0.038em;
  line-height: 0.98;
}
h2 {
  font-size: clamp(1.9rem, 4.4vw, 3.1rem);
  letter-spacing: -0.03em;
}
h3 {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  letter-spacing: -0.018em;
  line-height: 1.2;
}

p { max-width: var(--read); }
.lead {
  font-size: clamp(1.05rem, 1.7vw, 1.3rem);
  line-height: 1.55;
  color: var(--mut);
  max-width: 58ch;
}

strong, b { font-weight: 600; color: var(--ink); }

/* Column heads. Condensed gothic caps over a rule is how every printed
   schedule labelled its columns. */
.col-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ══ LAYOUT ══════════════════════════════════════════════════════════════
   The column is centred ONCE and everything inside it is left-flush. Boxes of
   different widths that each carry margin-inline:auto share a CENTRE axis, not
   a left edge, and the result is text that steps in and out down the page. */

.wrap {
  width: 100%;
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

section { position: relative; }

.band { padding-block: clamp(84px, 13vh, 168px); }
.band + .band { border-top: 1px solid var(--line); }

/* More space above a heading than below it — the heading belongs to what
   follows it, not to what came before. */
.band > .wrap > h2 { margin-bottom: 20px; }
.band > .wrap > h2 + .lead { margin-bottom: 52px; }

/* ══ THE RULE THAT DRAWS ITSELF ══════════════════════════════════════════
   A 1px hairline is the cheapest possible piece of motion and it gives the eye
   something to follow at every section boundary. */
.band + .band { border-top-color: transparent; }
.band + .band::before {
  content: '';
  position: absolute; inset-inline: 0; top: 0; height: 1px;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.1s var(--ease);
}
.band + .band.in::before,
html:not(.js) .band + .band::before { transform: scaleX(1); }

/* ══ NAV ═════════════════════════════════════════════════════════════════
   A translucent layer the content scrolls UNDER, not an opaque strip that eats
   a fixed band of the viewport. */

.nav {
  position: fixed; inset-inline: 0; top: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 14px var(--gutter);
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid transparent;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.nav.scrolled {
  border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
}
.nav-mark { display: flex; align-items: center; gap: 10px; }
.nav-mark svg { width: 26px; height: 26px; }
.nav-mark span {
  font-weight: 700; font-size: 15px; letter-spacing: 0.22em;
}
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-links a {
  font-size: 14px; color: var(--mut);
  transition: color .25s var(--ease);
}
.nav-links a:hover, .nav-links a:focus-visible { color: var(--ink); }
@media (max-width: 720px) { .nav-links { display: none; } }
/* At 393px the full-label CTA took half the bar and crowded the wordmark. The
   label shortens rather than the button shrinking, so the target stays well
   over the 24px minimum. */
@media (max-width: 560px) {
  .nav { padding-inline: 18px; }
  .nav .btn { padding: 11px 15px; font-size: 13px; }
  .nav .btn .long { display: none; }
}
.nav .btn .short { display: none; }
@media (max-width: 560px) { .nav .btn .short { display: inline; } }

/* ══ BUTTONS ═════════════════════════════════════════════════════════════
   The press is the feedback. It fires on pointer-down, not on release — the
   moment lag appears, directness falls off a cliff. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 26px;
  border-radius: 8px;
  font-size: 14px; font-weight: 600; letter-spacing: 0.04em;
  white-space: nowrap;
  transition: transform 140ms var(--ease),
              background-color 220ms var(--ease),
              border-color 220ms var(--ease),
              color 220ms var(--ease);
}
.btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

.btn-primary { background: var(--accent); color: #0A0B0C; border: 1px solid var(--accent); }
.btn-ghost   { background: transparent; color: var(--ink); border: 1px solid var(--line-strong); }

/* Hover only where a cursor actually exists. On a touch device :hover fires on
   tap and sticks, which reads as a stuck button. */
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: var(--accent-hi); border-color: var(--accent-hi); box-shadow: var(--glow); }
  .btn-ghost:hover   { border-color: var(--accent); color: var(--accent-text); box-shadow: var(--glow); }
}
.btn:active { transform: scale(.972); transition-duration: 90ms; }

/* ══ THE PLAN SHEET ══════════════════════════════════════════════════════
   The signature object. Not a screenshot and not a mock dashboard: the
   product's own surface, drawn in code so it stays sharp at any density, reads
   at 360px, and can hold live motion.

   Rows land ON rules. Rules are structure here, never ornament. */

.sheet {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  /* Shadows carry an offset and a soft blur. A zero-offset coloured halo is
     decoration, not depth. */
  box-shadow: 0 32px 64px -24px rgba(0, 0, 0, .7),
              0 2px 8px rgba(0, 0, 0, .3);
}

.sheet-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--raised);
}
.sheet-title {
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.02em; color: var(--mut);
}
.sheet-bar .spacer { margin-left: auto; }

/* SCROLLED-TO IS FINE; CLIPPED-OFF IS NOT. A five-column plan does not fit a
   393px phone, and `overflow:hidden` on the sheet turned that into a Status
   column that simply was not there. The table gets its own scroll container so
   nothing is ever lost — and below 700px the WEIGHT column is dropped, because
   a bar is the one column whose meaning is already carried by the number
   beside it. */
.sheet-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 700px) {
  .plan th, .plan td { padding: 11px 12px; font-size: 12.5px; }
  .plan .w-col { display: none; }
  .stamp { font-size: 9px; letter-spacing: .1em; padding: 3px 6px; }
}
@media (max-width: 420px) {
  .plan th, .plan td { padding: 10px 9px; }
  .sheet-bar { padding: 11px 12px; }
  .sheet-title { font-size: 11.5px; }
}

/* The live dot. It pulses because something is actually running; if nothing
   were, it would be the wrong signal to send. */
.live-dot {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent-text);
}
.live-dot::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,255,255,.55), 0 0 10px rgba(255,255,255,.5); }
  70%  { box-shadow: 0 0 0 7px transparent,          0 0 14px rgba(255,255,255,0); }
  100% { box-shadow: 0 0 0 0 transparent,            0 0 0   rgba(255,255,255,0); }
}

/* The grid itself */
.plan { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.plan th, .plan td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}
.plan thead th {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--dim);
  background: color-mix(in srgb, var(--raised) 60%, transparent);
  border-bottom-color: var(--line-strong);
  white-space: nowrap;
}
.plan tbody tr:last-child td { border-bottom: 0; }
.plan .num { text-align: right; font-variant-numeric: tabular-nums lining-nums; }
.plan .chan { font-weight: 600; color: var(--ink); white-space: nowrap; }

/* Status is a stamp, not a pill: a planner stamped the sheet. */
.stamp {
  display: inline-block;
  font-size: 10px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 3px; border: 1px solid;
  white-space: nowrap;
}
.stamp.running { color: #0A0B0C; border-color: #FFFFFF; background: #FFFFFF; box-shadow: var(--glow); }
.stamp.paused  { color: var(--warn); border-color: rgba(255,255,255,.34); background: rgba(255,255,255,.07); }
.stamp.stopped { color: var(--loss); border-color: rgba(255,255,255,.16); background: transparent; }

/* The weight bar — how a printed plan drew spend. Scales from the left because
   that is the direction the eye reads the column. */
.weight {
  /* BLOCK, not inline. height has no effect on an inline box, so as a bare
     <span> this rendered as a zero-height nothing and the whole WEIGHT column
     was empty — the bars were being animated perfectly and painting nowhere. */
  display: block;
  position: relative; height: 6px; border-radius: 3px;
  background: color-mix(in srgb, var(--line-strong) 55%, transparent);
  overflow: hidden; min-width: 56px;
}
.weight i {
  position: absolute; inset: 0;
  transform-origin: left center; transform: scaleX(var(--w, 0));
  background: var(--accent);
  border-radius: inherit;
  transition: transform 1.2s var(--ease);
}
.weight i { box-shadow: 0 0 10px rgba(255,255,255,.28); }
.weight.is-warn i { background: var(--warn); box-shadow: none; }
.weight.is-off  i { background: var(--line-strong); box-shadow: none; }

/* THE UNKNOWN CELL. The product's hardest-won property, made visible: a metric
   that is not known renders as a dash, never as a zero. A zero is a claim. */
.unknown { color: var(--dim); font-style: normal; }

/* ══ HERO ════════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  padding-top: clamp(124px, 17vh, 190px);
  padding-bottom: clamp(72px, 11vh, 132px);
  overflow: hidden;
}

/* The ground is not flat. A single very soft cyan light, low and to the left,
   the way a desk lamp falls across a sheet — it is what stops a dark page
   reading as a void. It never touches the reading column. */
.hero::before {
  content: '';
  position: absolute; inset: -20% -10% auto -30%;
  height: 90%;
  background: radial-gradient(60% 55% at 22% 35%,
              rgba(255,255,255,.075) 0%, transparent 68%);
  pointer-events: none;
  z-index: 0;
}
.hero > .wrap { position: relative; z-index: 1; }

.hero h1 { margin-bottom: 26px; }
.hero .lead { margin-bottom: 38px; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }
@media (max-width: 560px) {
  .hero-cta { display: grid; grid-template-columns: 1fr; }
  .hero-cta .btn { width: 100%; }
}
.hero-note { font-size: 13px; color: var(--dim); max-width: 46ch; }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(44px, 6vw, 72px);
  align-items: center;
}
@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); }
}

/* ══ THE AGENT EXCHANGE ══════════════════════════════════════════════════
   What you say, and what it does about it. Drawn as the product's own chat,
   because the product IS a conversation. */

.chat { display: grid; gap: 12px; }
.turn {
  padding: 14px 16px;
  border-radius: 10px;
  font-size: 14.5px;
  line-height: 1.55;
  max-width: 100%;
}
.turn.you {
  background: var(--raised);
  border: 1px solid var(--line);
  color: var(--ink);
  justify-self: end;
  max-width: 88%;
}
.turn.it {
  background: var(--panel);
  border: 1px solid rgba(255,255,255,.16);
  color: var(--mut);
}
.turn.it strong { color: var(--ink); }

/* The tool trace. This is the part competitors hide; here it is the argument. */
.trace {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px dashed rgba(255,255,255,.16);
  display: grid; gap: 7px;
}
.trace-row {
  display: flex; align-items: center; gap: 9px;
  font-size: 12px; color: var(--dim);
}
.trace-row svg { width: 13px; height: 13px; flex: 0 0 auto; color: var(--accent); }
.trace-row b { color: var(--mut); font-weight: 600; }

/* ══ FIGURES THAT COUNT ══════════════════════════════════════════════════
   Not a stat strip. Each figure sits with the sentence that makes it mean
   something, and each one is a fact about the software, never about a result
   somebody else got. */

.figures {
  display: grid;
  gap: clamp(28px, 4vw, 52px);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-top: 8px;
}
.figure { border-top: 1px solid var(--line-strong); padding-top: 18px; }
.figure .n {
  display: block;
  font-size: clamp(2.3rem, 4.6vw, 3.4rem);
  font-weight: 700; line-height: 1;
  letter-spacing: -0.04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
  margin-bottom: 10px;
}
.figure .n .suf { color: var(--accent-text); }
.figure p { font-size: 14.5px; color: var(--mut); max-width: 30ch; }

/* ══ SURFACE CARDS ═══════════════════════════════════════════════════════
   Deliberately NOT a grid of same-size icon-heading-text cards. Each surface
   gets a row whose weight matches how much of the product it is, and the
   drawn frame beside it shows the actual thing. */

.surface {
  display: grid;
  gap: clamp(26px, 4vw, 56px);
  align-items: center;
  padding-block: clamp(40px, 6vh, 72px);
  border-top: 1px solid var(--line);
}
.surface:first-of-type { border-top: 0; padding-top: 0; }
@media (min-width: 900px) {
  .surface { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }
  /* The columns have to swap with the content, not just the order. Reordering
     alone put the flipped rows' product frame in the NARROW column, so Ad Studio
     rendered visibly smaller than Launch for no reason a reader could see. The
     frame always takes the wide side; the prose always takes the narrow one. */
  .surface.flip { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
  .surface.flip > *:first-child { order: 2; }
}
.surface h3 { margin-bottom: 12px; }
.surface p { color: var(--mut); font-size: 15.5px; }

/* ══ THE GUARDRAIL BLOCK ═════════════════════════════════════════════════
   Spend is the thing a buyer is actually frightened of. It gets the page's
   only inverted surface, because it is the page's most important claim. */

.gate {
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  padding: clamp(28px, 4vw, 48px);
  position: relative;
  overflow: hidden;
}
.gate h3 { margin-bottom: 14px; }
.gate p { color: var(--mut); }
.gate-list { list-style: none; display: grid; gap: 14px; margin-top: 30px; }
/* The box is 1240px and the prose is capped at a readable 68ch, which left the
   right half of the panel empty. The list is the part that can take the width. */
@media (min-width: 860px) {
  .gate-list { grid-template-columns: 1fr 1fr; gap: 20px 44px; }
}
.gate-list li {
  display: grid; grid-template-columns: 20px 1fr; gap: 13px;
  align-items: start;
  font-size: 15px; color: var(--mut);
}
.gate-list svg { width: 18px; height: 18px; margin-top: 3px; color: var(--accent); }
.gate-list b { color: var(--ink); font-weight: 600; }

/* ══ FOOTER ══════════════════════════════════════════════════════════════ */

.foot {
  border-top: 1px solid var(--line);
  padding-block: 56px;
  font-size: 14px; color: var(--dim);
}
.foot-row {
  display: flex; flex-wrap: wrap; gap: 22px 40px;
  align-items: center; justify-content: space-between;
}
.foot a { color: var(--mut); transition: color .25s var(--ease); }
@media (hover: hover) and (pointer: fine) { .foot a:hover { color: var(--ink); } }
.foot-links { display: flex; flex-wrap: wrap; gap: 22px; }

/* ══ MOTION ══════════════════════════════════════════════════════════════
   ONE authored moment per section, from an already-visible default. Every
   hiding rule below is scoped to html.js, which the script adds to ITSELF —
   so a script that fails to load or parse leaves every word on screen.
   Text is the product; it fails open. */

html.js .rise {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity .6s linear,
              transform .85s var(--ease);
  will-change: opacity, transform;
}
html.js .rise.in {
  opacity: 1; transform: none; will-change: auto;
}

/* Travel scales with the surface. 18px is 4.6% of a 390px phone and 1% of a
   1680px display — the same distance that reads as motion on one reads as
   nothing on the other. */
@media (min-width: 1100px) {
  html.js .rise { transform: translate3d(0, 30px, 0); }
}

/* Stagger: 30–80ms between items. Longer and the interface feels slow. */
html.js .stagger > * { transition-delay: calc(var(--i, 0) * 55ms); }

@media (prefers-reduced-motion: reduce) {
  html.js .rise,
  html.js .rise.in { opacity: 1 !important; transform: none !important; transition: none !important; }
  .live-dot::before { animation: none; }
  .weight i { transition: none; }
  .band + .band::before { transform: scaleX(1) !important; transition: none !important; }
}
