/* ------------------------------------------------------------------------
   site.css — the pages around the atlas: landing, FAQ, contact, methodology.

   The page DESCENDS. Hero and the narrative beats float as glass over a
   fixed sky, so scrolling reads as content moving through weather rather
   than as the weather scrolling away. Below them the page lands on
   `--ground` — a solid surface, gradient-joined at the top — and the denser
   material sits there in an ordinary column. Sky above, ground below.

   Not loaded by /atlas/, which draws its own chrome.
   Carries no colour of its own — every value is a var() into tokens.css.
   ---------------------------------------------------------------------- */


/* ==================================================================== NAV */
/* A fixed glass pill, centred, full width minus 28px. It carries the one
   persistent primary action; every other CTA on a page is glass. */

.nav {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 6px;
  width: calc(100% - 28px);
  max-width: var(--page-max-width);
  padding: 7px 7px 7px 16px;
  border-radius: var(--radius-pill);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-right: 6px;
  color: var(--ink);
  text-decoration: none;
  transition: color var(--t-theme);
}
.nav__links { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.nav__link {
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  font-size: var(--text-fine);
  color: var(--ink-soft);
  text-decoration: none;
  transition: color var(--t-ui), background-color var(--t-ui);
}
.nav__link:hover { color: var(--ink); background: var(--wash); }
.nav__link[aria-current="page"] { color: var(--ink); font-weight: var(--weight-strong); }

/* The compact nav. A kebab rather than a burger: the bar already carries a
   primary button and a switch, and three dots read as "the rest of it"
   where three bars read as "the whole menu, including what you can see". */
.nav__menu {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  padding: 0;
  border: 1px solid var(--ink-hairline);
  border-radius: var(--radius-pill);
  background: var(--wash);
  color: var(--ink-soft);
  cursor: pointer;
  transition: color var(--t-ui), background-color var(--t-ui);
}
.nav__menu:hover { color: var(--ink); }
/* Three dots from one element: the middle is the box, the outer two are its
   own shadows. The mark's dots are a SEQUENCE and mean something; these are a
   control and are deliberately uniform, so the two cannot be confused. */
.nav__menu span {
  width: 3px; height: 3px;
  border-radius: var(--radius-pill);
  background: currentColor;
  box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
}
.nav__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 190px;
  display: flex;
  flex-direction: column;
  padding: 7px;
  border-radius: var(--radius-card);
}
.nav__panel a {
  padding: 10px 13px;
  border-radius: var(--radius-pill);
  font-size: var(--text-fine);
  color: var(--ink-soft);
  text-decoration: none;
  transition: color var(--t-ui), background-color var(--t-ui);
}
.nav__panel a:hover { color: var(--ink); background: var(--wash); }
.nav__panel a[aria-current="page"] { color: var(--ink); font-weight: var(--weight-strong); }

/* The sky is fixed, so the page needs its own stacking context above it. */
.page { position: relative; z-index: 1; }


/* =================================================================== HERO */

.hero {
  position: relative;
  min-height: 80svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: 88px 64px;
}
.hero__inner {
  display: flex; flex-direction: column; align-items: center;
  gap: 22px; max-width: 46rem;
}
.hero .lead { max-width: 34rem; }
.hero__cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 6px; }

/* One orchestrated entrance, then the page is still. There is no
   scroll-triggered anything: the sky already moves, and a page that also
   moves is two weathers at once. */
.rise { opacity: 0; transform: translateY(14px); animation: rise .8s cubic-bezier(.2,.7,.3,1) forwards; }
.rise:nth-child(1) { animation-delay: .05s; }
.rise:nth-child(2) { animation-delay: .13s; }
.rise:nth-child(3) { animation-delay: .21s; }
.rise:nth-child(4) { animation-delay: .29s; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* Scroll cue: the mark's four dots on their own axis, falling in sequence.
   The mark ascends; the cue is the same four dots going the other way, which
   is both the correct affordance and the brand's own gesture reversed. */
.cue {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: flex-end;
  gap: 7px;
  height: 26px;
  opacity: .55;
}
.cue .seq-dot { animation: cue-fall 2.6s ease-in-out infinite; }
.cue .seq-dot--1 { margin-bottom: 13px; }
.cue .seq-dot--2 { margin-bottom: 8px;  animation-delay: .14s; }
.cue .seq-dot--3 { margin-bottom: 3px;  animation-delay: .28s; }
.cue .seq-dot--4 { margin-bottom: 0;    animation-delay: .42s; }
@keyframes cue-fall {
  0%, 100% { transform: translateY(0);   opacity: .4; }
  45%      { transform: translateY(6px); opacity: 1; }
}


/* A compact header for a page that is not the landing: enough sky to say
   which product this is, and then straight down to the ground where the
   dense material lives. The top padding clears the fixed nav pill. */
.head { padding-block: 104px 72px; }
/* Per-page rhythm. The default `--section-rhythm` is set for a page of dense
   reference material; the landing is five short beats, and the FAQ and contact
   heads are a single line each with the whole page waiting under them. */
.home .section { padding-block: clamp(48px, 6vh, 76px); }
.faq-page .head { padding-block-end: 16px; }
.faq-page .ground > .section { padding-block-start: 32px; }
.contact .head { padding-block-end: 16px; }
.contact .ground > .section { padding-block-start: 28px; }
.head .lead a { color: var(--ink); text-underline-offset: 3px; }
.head .lead a:hover { color: var(--accent); }


/* ================================================================= FIGURE */
/* The one place a number is allowed to be large. Three cells divided by
   hairlines; the unit sits in --ink-faint and every figure is tabular. */

.figure {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  gap: 4px;
  padding: 34px 38px;
  border-radius: var(--radius-card);
  margin-top: var(--space-8);
}
.figure__cell { display: flex; flex-direction: column; gap: 7px; }
.figure__cell + .figure__cell {
  border-left: 1px solid var(--ink-hairline);
  padding-left: 30px;
  transition: border-color var(--t-theme);
}
.figure__val {
  font-size: clamp(1.9rem, 4.4vw, 2.9rem);
  font-weight: var(--weight-strong);
  line-height: 1;
  letter-spacing: -.03em;
}
.figure__op { color: var(--ink-faint); font-weight: var(--weight-body); }
.figure__unit {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color var(--t-theme);
}


/* ================================================================== STEPS */
/* Target / Intercept / Deliver / Measure take the mark's four dots, one
   each. The mark is a sequence, and this is the one place on the page
   where the content genuinely is one. The first three are the sortie and
   sit in a row; Measure is what outlives it, so it takes the full width
   underneath rather than a fourth column.

   Two states, ONE footprint. The card rests condensed and opens under the
   pointer, but both paragraphs are stacked in the same grid cell, so the
   card is always the height of the longer one and opening it cannot move
   anything else on the page — the only thing that moves is the card, a
   3.5 % lift out of the grid onto its own z-index. The dot keeps its rung
   on the mark's 5/7/10/14 ladder and its blur while the card rests, then
   contracts and fades as the icon's strokes draw themselves in over the
   same 26px cell — one shape becoming another, not two shapes stacked.
   Devices with no pointer get the open state permanently. */

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.step {
  display: flex; flex-direction: column; gap: 13px;
  padding: 26px 24px 24px;
  border-radius: var(--radius-card);
  position: relative;
  /* Restates `.glass`'s background fade, which this shorthand replaces. */
  transition: transform .34s var(--ease), box-shadow .34s var(--ease),
              border-color .34s var(--ease), background var(--t-theme);
}
.step:is(:hover, :focus-visible) {
  transform: scale(1.035);
  z-index: 2;
  border-color: var(--glass-line-lit);
  box-shadow: var(--glass-shadow-lg), var(--glass-inner);
}
.step--wide { grid-column: 1 / -1; }
/* Full width means full measure: the shared 62ch cap would wrap this card's
   one line halfway across a container twice that wide. */
.step--wide .body { max-width: none; }

/* The dot and the icon share one 26px cell, both centred on the same axis. */
.step__dot { display: grid; place-items: center; width: 26px; height: 26px; }
.step__dot > * { grid-area: 1 / 1; }
.step__dot .seq-dot {
  transition: transform .34s var(--ease), opacity .22s var(--ease),
              background var(--t-theme);
}
.step:is(:hover, :focus-visible) .seq-dot { opacity: 0; transform: scale(.35); }
.step__icon { display: block; width: 26px; height: 26px; }
/* Every path carries `pathLength="1"`, so one dashoffset draws any of them. */
.step__stroke {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  transition: stroke-dashoffset .44s var(--ease), opacity .22s var(--ease);
}
.step:is(:hover, :focus-visible) .step__stroke { stroke-dashoffset: 0; opacity: .9; }
.step__stroke--b { transition-delay: .08s; }

/* Both paragraphs in row 1 / column 1, top-aligned. Top, not centred: the
   longest card in the row sets the block's height, and centring would leave
   the three short lines each at a different height. Aligned first lines and
   air underneath is the trade for a card that never resizes. */
.step__copy { display: grid; }
.step__copy > * {
  grid-area: 1 / 1;
  align-self: start;
  transition: opacity .28s var(--ease), transform .28s var(--ease);
}
.step__full { opacity: 0; transform: translateY(5px); }
.step:is(:hover, :focus-visible) .step__short { opacity: 0; transform: translateY(-5px); }
.step:is(:hover, :focus-visible) .step__full { opacity: 1; transform: none; }

/* Under 900px every card is its own row, so there is no taller sibling to
   reserve height against and the condensed state buys nothing: the card
   carries its full copy with the icon already drawn.
   
   Keyed on the LAYOUT, never on `hover` / `any-hover`. A touch-capable
   laptop reports its touchscreen as the primary pointer even with a mouse
   attached, so `hover: none` matches on machines that hover perfectly well
   — gating this on it pinned all four cards permanently open. */
@media (max-width: 900px) {
  .step__short { display: none; }
  .step__full { opacity: 1; transform: none; }
  .step__stroke { stroke-dashoffset: 0; opacity: .9; }
  .step .seq-dot { opacity: 0; }
}


/* ========================================================== ATLAS INVITE */
/* The atlas as a shape, not a dashboard. It carries NO figures — no stat
   stack, no conversion readout, no month bars — because a number on this
   page would be an assertion the page cannot back, and the honesty line
   right below it says the atlas is not a sales tool. What it shows is the
   instrument: a window, three named views, a field of 45 km cells, and the
   ramp that reads them. The whole thing is one link into the real thing. */

.aw {
  display: block;
  border-radius: var(--radius-window);
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  transition: transform var(--t-ui), box-shadow var(--t-ui),
              background var(--t-theme), border-color var(--t-theme);
}
.aw:hover { transform: translateY(-1px); }

.aw__bar {
  display: flex; align-items: center; gap: 14px;
  padding: 0 14px;
  height: var(--topbar-height);
  border-bottom: 1px solid var(--ink-hairline);
  transition: border-color var(--t-theme);
}
.aw__title { font-size: 15px; font-weight: var(--weight-strong); letter-spacing: -.015em; }

/* The three views, named exactly as the application names them
   (src/pages/atlas.astro) — and keyed the way the application's own panel keys
   them: the identity colour IS the colour of the name. No dot beside it. The
   hue is the vivid trio, which is the set authored for type; the deepened one
   is for patches and the map. It keys the name, never a magnitude. */
.aw__views {
  display: inline-flex; gap: 2px; padding: 2px;
  border-radius: var(--radius-control);
  background: var(--wash);
  border: 1px solid var(--ink-hairline);
  transition: background var(--t-theme), border-color var(--t-theme);
}
.aw__view {
  display: inline-flex; align-items: center;
  padding: 5px 11px; border-radius: var(--radius-default);
  font-size: var(--text-app-lg); color: var(--sw);
  white-space: nowrap;
  transition: color var(--t-theme), background-color var(--t-ui);
}
.aw__view--on {
  font-weight: var(--weight-strong);
  background: linear-gradient(145deg, var(--glass-a), var(--glass-b));
  box-shadow: var(--glass-inner), 0 2px 8px #0f172a1f;
}

/* Ink, not the accent. The accent is spent once per screen on the action
   that matters — here that is the hero's, and the nav's persistent one. A
   third chromatic call to action on the same page is how an accent stops
   meaning "this one". The window itself is the affordance. */
.aw__open {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--text-fine);
  font-weight: var(--weight-strong);
  color: var(--ink);
  white-space: nowrap;
}
.aw__open svg { transition: transform var(--t-ui); }
.aw:hover .aw__open svg { transform: translateX(3px); }

.aw__stage {
  position: relative;
  min-height: 372px;
  padding: 16px;
  display: flex; flex-direction: column; justify-content: flex-end;
  background:
    radial-gradient(88% 74% at 22% 16%, #ffffff14 0, #ffffff00 60%),
    linear-gradient(160deg, var(--ground-sunk), var(--ground));
  transition: background var(--t-theme);
}
.aw__map { position: absolute; inset: 0; width: 100%; height: 100%; }
.aw__hint {
  position: absolute; top: 16px; left: 16px;
  display: inline-flex; align-items: center;
  padding: 6px 12px; border-radius: var(--radius-pill);
  font-size: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The ramp, with the label that names what it reads — and no floor, unit or
   ceiling, because those are numbers. Six equal steps, 1px gaps, no border:
   the legend in the application carries the same shape with its scale on. */
.aw__legend {
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  width: 260px;
  padding: 11px 13px;
  border-radius: var(--radius-control);
}
.aw__ramp { display: flex; height: 8px; border-radius: 3px; overflow: hidden; gap: 1px; }
.aw__ramp span { flex: 1; }

.aw__foot {
  padding: 9px 16px;
  border-top: 1px solid var(--ink-hairline);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--ink-faint);
  transition: color var(--t-theme), border-color var(--t-theme);
}


/* ================================================================= GROUND */
/* Below the sky the page lands on a solid surface, gradient-joined at the
   top so there is no seam, and the reference material sits there in an
   ordinary column. */

.ground {
  position: relative;
  z-index: 1;
  background: linear-gradient(180deg, transparent 0, var(--ground) 190px, var(--ground) 100%);
  transition: background var(--t-theme);
}

.rule {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--ink-hairline);
  transition: border-color var(--t-theme);
}
.rule .eyebrow { white-space: nowrap; }
.rule__line { flex: 1; height: 1px; background: var(--ink-hairline); transition: background var(--t-theme); }

.band {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 20px;
  padding: 28px 30px;
  border-radius: var(--radius-card);
}


/* ==================================================================== FAQ */
/* <details>, not a JavaScript accordion: it opens, it is keyboard operable,
   it is findable by the browser's own in-page search, and this page ships
   no script of its own. */

.faq-group { display: flex; flex-direction: column; }
.faq {
  border-bottom: 1px solid var(--ink-hairline);
  transition: border-color var(--t-theme);
}
.faq summary {
  cursor: pointer;
  padding: 16px 0;
  list-style: none;
  display: flex; align-items: baseline; gap: 12px;
  font-size: 17px;
  font-weight: var(--weight-strong);
  letter-spacing: -.012em;
  transition: color var(--t-ui);
}
.faq summary::-webkit-details-marker { display: none; }
/* A plus that becomes a minus. The minus is the CSS escape `\2212`, never a
   literal character, so no encoding step can corrupt it. */
.faq summary::before {
  content: "+";
  color: var(--ink-faint);
  font-weight: var(--weight-body);
  width: 14px; flex: 0 0 auto;
  transition: color var(--t-theme);
}
.faq[open] summary::before { content: "\2212"; }
.faq summary:hover { color: var(--ink); }
.faq__a { padding: 0 0 18px 26px; display: flex; flex-direction: column; gap: 12px; }
.faq__a p { color: var(--ink-soft); max-width: var(--measure); transition: color var(--t-theme); }


/* =============================================================== CONTACT */

.mailto {
  display: inline-block;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  font-weight: var(--weight-display);
  letter-spacing: -.024em;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 2px;
  transition: color var(--t-ui), border-color var(--t-ui);
}
.mailto:hover { color: var(--accent); }

.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.card {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--card-padding);
  border-radius: var(--radius-card);
  color: inherit;
  text-decoration: none;
  transition: transform var(--t-ui), box-shadow var(--t-ui),
              background var(--t-theme), border-color var(--t-theme);
}
a.card:hover { transform: translateY(-1px); }
.card__name { font-size: 19px; font-weight: var(--weight-strong); letter-spacing: -.01em; }
.card__note { font-size: var(--text-body); color: var(--ink-soft); transition: color var(--t-theme); }


/* ================================================================= FOOTER */

.foot {
  padding-block: 40px 56px;
  border-top: 1px solid var(--ink-hairline);
  transition: border-color var(--t-theme);
}
.foot__row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 14px;
}
/* The lockup is an <img>, so the line it sits on needs to align it rather
   than let it sit on the text baseline with a descender's worth of gap. */
.foot__id { display: flex; align-items: center; gap: 10px; }
.foot__links { display: flex; flex-wrap: wrap; gap: 18px; }
.foot__links a {
  font-size: var(--text-fine);
  color: var(--ink-faint);
  text-decoration: none;
  transition: color var(--t-ui);
}
.foot__links a:hover { color: var(--ink); }


/* ============================================================= RESPONSIVE */
/* Cards go to one column under 900px; the nav's links move into the kebab
   panel at the same breakpoint. */

@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__menu { display: inline-flex; }
  .steps, .cards { grid-template-columns: 1fr; }
  .figure { grid-template-columns: 1fr; gap: 22px; padding: 26px; }
  .figure__cell + .figure__cell {
    border-left: 0; padding-left: 0;
    border-top: 1px solid var(--ink-hairline); padding-top: 20px;
  }
  .aw__stage { min-height: 260px; }
  .aw__legend { width: 100%; }
  .aw__bar { gap: 10px; }
  .aw__views { display: none; }
}

@media (max-width: 560px) {
  .nav { padding-left: 12px; }
  .hero { padding-block: 104px 80px; }
}

@media (prefers-reduced-motion: reduce) {
  .rise { opacity: 1; transform: none; }
}
