/* ══════════════════════════════════════════════════════════ tokens ══
   The face, both modes' colours, the focus ring and .btn are in Screens'
   ground.css, loaded before this sheet; theme.js applies the reader's mode
   before first paint. Here: the scale, which is this host's own.

   --pos and --magenta are aliased to teal here and nowhere shared: on this
   host they only ever mean "grew". lines.css in Screens reads --pos. */
:root {
  --t-h2:    clamp(1.75rem, 1.2rem + 1.6vw, 2.5rem);
  --t-h3:    clamp(1.15rem, 1rem + .5vw, 1.4rem);
  --t-lead:  1.125rem;
  --t-body:  1rem;
  --t-small: .875rem;
  --t-micro: .8125rem;

  --bay-lg: clamp(4rem, 8vw, 7rem);
  --bay-md: clamp(2.75rem, 5vw, 4.5rem);
  --r-lg: 12px;
  --r-md: 8px;
  --r-sm: 6px;
  --gap: 14px;
  /* Wide enough that a desktop is not a tablet with margins; long lines are capped in ch. */
  --maxw: 1360px;
  --gutter: clamp(16px, 4vw, 40px);

  --magenta: var(--grow);
  --pos: var(--grow);
  --t-meta: var(--t-micro);
  --m: 1;
}

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

html { overflow-x: clip; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.5;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-underline-offset: 3px; }

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

h1, h2, h3 { font-weight: 650; letter-spacing: -.02em; line-height: 1.08; margin: 0; text-wrap: balance; }
h3 { line-height: 1.2; }
p { margin: 0; }

[id] { scroll-margin-top: 1.5rem; }
/* A member's pages sit under the frame's sticky bar (frame.css), so a jump lands below it. */
.sheet [id] { scroll-margin-top: calc(var(--bar-h) + 1.5rem); }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* One surface. It used to be glass over a WebGL field; with nothing behind it to blur, a card is
   a card — the class keeps its name so the product and pricing markup did not have to change. */
.glass { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); }

/* ════════════════════════════════════════════════════════ the panel ══
   The hero, the closing band and the account forms' panel, ruled like a
   cutting mat. Here, not home.css: a layout cannot load a sheet. Lines, not
   a gradient, fading out before the edges so it never reads as a form.    */
.hero::before,
.close::before,
.auth-aside::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image:
    linear-gradient(var(--rule-hi) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule-hi) 1px, transparent 1px),
    linear-gradient(var(--rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule) 1px, transparent 1px);
  background-size: 160px 160px, 160px 160px, 32px 32px, 32px 32px;
  background-position: center;
  /* Strongest behind the scene, quiet behind the words. */
  -webkit-mask-image: radial-gradient(ellipse 70% 100% at 72% 40%, #000 25%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 100% at 72% 40%, #000 25%, transparent 100%);
  pointer-events: none;
}

/* What a member can do (Benefits): three plain lines, an ink tick each. No rules, cards or colour,
   so it reads as part of the promise rather than a feature grid. */
.hero-can { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 12px; max-width: 54ch; }
.hero-can li { display: flex; gap: 12px; align-items: flex-start; font-size: 1.0625rem; line-height: 1.4; text-wrap: pretty; }
.hero-can svg { flex: none; margin-top: 2px; fill: none; stroke: var(--ink); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hero-can b { font-weight: 650; }

/* ══════════════════════════════════════════════════════════ the list ══
   This month's list in its window (ListBoard) on /products, the plans'
   window on /pricing, and the cells the members' tables draw: rank, name,
   change, growth. The front page's list is climb.css's.                  */
.board { overflow: clip; background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--lift); }
.board-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 40px;
  padding: 24px 28px 20px;
}
.board-bar h2 { font-size: var(--t-h3); }
.board-bar p { font-size: var(--t-small); color: var(--ink-soft); max-width: 62ch; }
.board-empty { padding: 4px 28px 24px; color: var(--ink-soft); max-width: 70ch; }
.board-foot { padding: 16px 28px 18px; border-top: 1px solid var(--line); font-size: var(--t-small); color: var(--ink-soft); }
.board-foot a { color: var(--ink); font-weight: 600; }

.rank { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.pname { display: flex; flex-direction: column; min-width: 0; }
.pname b { font-size: 1.0625rem; font-weight: 650; }
.pname small { font-size: var(--t-micro); color: var(--ink-soft); }

.change { color: var(--ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.change b { color: var(--ink); font-weight: 650; }
.growth { text-align: end; white-space: nowrap; color: var(--ink-soft); font-weight: 600; font-variant-numeric: tabular-nums; }
.growth.grew { color: var(--grow); }

@media (max-width: 960px) {
  .board-bar, .board-foot, .board-empty { padding-inline: 20px; }
}

/* A whole-page crossfade when the switch is pressed, from theme.js. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 320ms; }

/* ══════════════════════════════════════════════════════════ header ══
   The public pages' (SiteHeader), and the account forms' with no links
   (AuthLayout). Static, not sticky: a bar that follows you is one more
   thing moving; a phone gets the join bar below instead. A member's pages
   have the frame's bar (MemberLayout, frame.css). The wordmark is
   ground.css's .brand.

   The links lead from the wordmark and the end group sits at the edge, so
   the links stay put whatever the end holds: Danish is wider, and signed
   in it holds the initials (and a waiting account's pill) instead.        */
.topbar {
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 28px);
  max-width: var(--maxw);
  margin-inline: auto;
  padding: 18px var(--gutter);
}

/* A step larger than the members' frame: the logo leads the public pages and the account screens. */
.topbar .brand,
.auth > .brand { font-size: 1.25rem; }

.topnav { display: flex; gap: 24px; margin-inline-start: clamp(4px, 1.5vw, 16px); white-space: nowrap; }
.bar-end { display: flex; align-items: center; gap: 18px; margin-inline-start: auto; white-space: nowrap; }

/* The bar's own links only, never the account menu's inside it, which frame.css draws. */
.topnav a,
.bar-end > a:not(.btn) {
  color: var(--ink-soft);
  font-size: .9375rem;
  text-decoration: none;
  transition: color 160ms ease-out;
}
.topnav a:hover,
.bar-end > a:not(.btn):hover { color: var(--ink); }

/* The page you are on (NavLink's "active", with aria-current="page"), as the admin host marks it:
   ink and a rule under it. Never teal, which means "grew". */
.topnav a.active { color: var(--ink); font-weight: 600; box-shadow: inset 0 -2px 0 var(--ink); }

/* Signed in, the initials' menu (AccountMenu). frame.css pins it under the member frame's sticky
   56px bar; this bar scrolls away, so the menu is placed on the page instead: under the button
   (the bar's 18px top padding and the control's height) and at the end of the 1360px column. */
.topbar #account {
  position: absolute;
  inset: calc(18px + var(--ctl-h) + 6px) max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter))) auto auto;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Signed in but not let in yet: where they stand, as a quiet pill rather than one more link. */
.bar-end a.waiting {
  color: var(--ink);
  font-size: .8125rem;
  font-weight: 600;
  padding: .3rem .7rem;
  border: 1px solid var(--line-hi);
  border-radius: 999px;
  white-space: nowrap;
}
/* On /waiting itself (NavLink's "active"): an ink rim, as the nav marks the page you are on. */
.bar-end a.waiting.active { border-color: var(--ink); background: var(--tint); }

/* The language switch (LanguageSwitch). The header draws it as a link like the others; here it is
   the members' frame, whose frame.css is shared with the admin host and has no rule for it, and
   /account, which has no bar, so it sits where the bar's end would be. */
.top-end .lang-switch,
.auth > .lang-switch {
  color: var(--ink-soft);
  font-size: .875rem;
  text-decoration: none;
  transition: color 160ms ease-out;
}
.top-end .lang-switch:hover,
.auth > .lang-switch:hover { color: var(--ink); }
.top-end .lang-switch { display: inline-flex; align-items: center; min-height: var(--ctl-h); padding-inline: 6px; }
.auth > .lang-switch { position: absolute; top: 18px; inset-inline-end: var(--gutter); }

/* A phone or a small tablet: the links take their own row under the bar, every one in sight.
   Behind a menu button they are found less often (NN/g), and four fit. Tall enough to tap; the
   active rule sits on the row's edge like a tab. 900px, the member frame's own break: in Danish
   one row needs about 860px, and at 830px "Log ind" and the join button broke onto two lines. */
@media (max-width: 900px) {
  .topbar { flex-wrap: wrap; row-gap: 10px; padding-bottom: 0; }
  .topnav {
    order: 3;
    flex-basis: 100%;
    margin-inline-start: 0;
    gap: clamp(16px, 5vw, 28px);
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .topnav a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* On a phone the hero's own "Start free" is on the first screen, so the bar keeps Sign in. A
   waiting account's pill leaves no room for the name beside the switch and the initials: the
   parcel stays as the way home, and the name stays for a screen reader. 520px, not a phone's
   usual 420: in Danish the join button beside "Log ind" needs about 500, and up to there the
   whole end dropped onto a row of its own, a 430px iPhone among them. */
@media (max-width: 520px) {
  /* Edge to edge, so a visitor's four links still fit a 360px phone. */
  .topnav { justify-content: space-between; gap: 8px; }
  .bar-end { gap: 14px; }
  .bar-end .btn { display: none; }
  .topbar:has(a.waiting) .brand-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* ═════════════════════════════════════════════════════════ join bar ══
   A visitor's way to join on a phone once the page's first join button has
   scrolled away, and only while none of the page's own is on screen
   (JoinBar, joinbar.js); the bar above does not follow you. Hidden, it is
   out of the tab order too, and with no script it never shows. */
.joinbar { display: none; }

@media (max-width: 900px) {
  .joinbar {
    display: block;
    position: fixed;
    inset: auto 0 0;
    z-index: 20;
    padding: 12px var(--gutter) max(12px, env(safe-area-inset-bottom));
    background: var(--paper);
    border-top: 1px solid var(--line);
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 220ms ease-out, visibility 0s 220ms;
  }
  .joinbar.on { transform: none; visibility: visible; transition: transform 220ms ease-out; }
  .joinbar .btn { width: 100%; }
  /* Room under the footer's last line, so the bar never covers it: the bar is 68px tall. */
  body:has(.joinbar) .foot { padding-bottom: calc(40px + 68px); }
  /* While it shows, a link reached with Tab scrolls clear of it rather than under it (WCAG 2.4.11). */
  html:has(.joinbar.on) { scroll-padding-bottom: calc(68px + 12px); }
}

@media (prefers-reduced-motion: reduce) {
  .joinbar, .joinbar.on { transition: none; }
}

/* ═══════════════════════════════════════════════════════ the error page ══
   Plain on purpose: it is reached when something broke. The 404 has the
   header, the band and the footer instead (home.css).                     */
.plain { padding-block: clamp(6rem, 22vh, 12rem); max-width: 46rem; }
.plain h1 { font-size: var(--t-h2); margin-bottom: 1rem; }
.plain-lede { color: var(--ink-soft); margin-bottom: 1.25rem; font-size: var(--t-lead); }
.plain-act {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 20px;
  border: 1.5px solid var(--ink);
  border-radius: var(--r-sm);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}
.plain-act:hover { background: var(--tint); }

/* Delays too: a 0 ms entrance that still waits its turn leaves the page blank for that long. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0ms !important;
    transition-delay: 0ms !important;
  }
}
