/* Reusable primitives shared by every section. Section-specific rules live in
   style.css. */

.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0;
  left: var(--container-pad);
  z-index: calc(var(--z-nav) + 1);
  padding: var(--sp-12) var(--sp-18);
  background: var(--c-white);
  color: var(--color-heading);
  font: var(--fw-bold) var(--fs-15) / 1 var(--font-sans);
  transform: translateY(-120%);
  transition: transform var(--t-fast);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* Visible keyboard focus for every interactive element. A .table-scroll joins
   them once it overflows and page.js gives it a tab stop of its own. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible,
.table-scroll:focus-visible {
  outline: var(--bw-2) solid var(--color-accent);
  outline-offset: 3px;
}

.section {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding-inline: var(--page-gutter);
  background: var(--bg-page);
}

/* Every light section closes on a hairline rule the full width of the page. The alt
   and deep surfaces mark the same seam with their own background, so carry no rule. */
.section:not(.section--alt):not(.section--deep) {
  border-bottom: var(--bw-1) solid var(--border-rule);
}

.section--alt {
  background: var(--bg-page-alt);
}

.section--deep {
  background: var(--bg-deep);
}

.container {
  display: flex;
  align-items: flex-start;
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

/* Every section puts its rail edge on the same x so the accent line reads as one
   unbroken rule down the page. The footer reaches it from a wider shell (see
   --footer-* in variables.css) rather than by sharing these values. */

.rail {
  position: relative;
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  align-self: stretch;
  flex: 0 0 var(--rail-width);
  width: var(--rail-width);
  padding-block: var(--rail-pad-y);
  /* Figma measures its 28px inset from the inside of the accent stroke, so the
     rule has to come out of the padding for the labels to land on x=257. */
  padding-right: calc(var(--rail-gap) - var(--rail-border));
  border-right: var(--rail-border) solid var(--color-accent);
}

/* Figma 315:2806 — the key dates rail is the one that pads 30px rather than 28
   to its border, and runs on 64px of vertical padding instead of 76px. */
.rail--short {
  padding-block: var(--sp-64);
  padding-right: calc(30px - var(--rail-border));
}

/* Sticky, as the Figma component is, but offset by the bar: Figma has no fixed
   header in its render, so its top-0 would park the labels behind ours. */
.rail__stack {
  position: sticky;
  top: var(--header-height);
  display: flex;
  flex-direction: column;
  gap: var(--sp-9);
  width: 100%;
  text-align: right;
}

.rail__marker {
  position: absolute;
  top: 84px;
  right: -6px;
  width: var(--rail-marker);
  height: var(--rail-marker);
  background: var(--color-accent);
}

.rail__marker--flush {
  top: 72px;
}

.section__content {
  position: relative;
  z-index: var(--z-content);
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: flex-start;
  align-self: stretch;
  gap: var(--block-gap);
  min-width: 0;
  padding: var(--content-pad-y) var(--content-pad-x);
}

/* The design's 1350px content column. Capping rather than fixing the width is
   pixel-identical at 1710px and simply shrinks on narrower viewports. */
.section__content--fixed {
  flex: 1 1 auto;
  max-width: var(--content-width);
}

.label {
  display: block;
  font-family: var(--font-mono);
  font-weight: var(--fw-regular);
  line-height: normal;
}

.label--seq {
  font-size: var(--fs-13);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide-132);
  text-transform: uppercase;
  color: var(--color-heading);
}

.label--msg {
  font-size: var(--fs-11);
  letter-spacing: var(--ls-wide-132);
  text-transform: uppercase;
  color: var(--color-muted);
}

.label--tag {
  font-size: var(--fs-13);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide-132);
  text-transform: uppercase;
  color: var(--color-accent);
}

/* Only the home page accents its rail tag. The three document pages draw it in
   the same muted grey as MSG= above it (602:6511, 1216:17369, 1216:17624). */
body[data-page='policies'] .label--tag,
body[data-page='fees'] .label--tag,
body[data-page='agreements'] .label--tag {
  color: var(--color-muted);
}

.label--eyebrow {
  font-size: var(--fs-12);
  letter-spacing: var(--ls-wide-192);
  text-transform: uppercase;
  color: var(--color-on-dark-muted);
}

.label--eyebrow-accent {
  color: var(--color-accent);
}

.label--group {
  font-size: var(--fs-11);
  letter-spacing: var(--ls-wide-198);
  text-transform: uppercase;
  color: var(--color-accent);
}

.label--status {
  font-size: var(--fs-12);
  letter-spacing: var(--ls-wide-1);
  text-transform: uppercase;
  color: var(--color-muted);
}

.label--status-live {
  color: var(--color-accent);
}

.rail--on-dark .label--seq {
  color: var(--c-white);
}

.rail--on-dark .label--msg {
  color: var(--color-on-dark-muted);
}

/* 455:2258 — Subscribe's third label is drawn as a second MSG line, not the accent
   tag the light sections use: 11px Regular in Gull Gray, not 13px SemiBold in Bondi
   Blue. The Footer's rail (451:1970) keeps the tag, so the two differ here alone. */
.rail--on-dark .label--tag {
  font-size: var(--fs-11);
  font-weight: var(--fw-regular);
  color: var(--color-on-dark-muted);
}

.rail--footer .label--seq {
  color: var(--color-on-dark);
}

.rail--footer .label--tag {
  color: var(--color-accent);
}

.h1 {
  max-width: var(--measure-1428);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-108);
  font-weight: var(--fw-bold);
  line-height: var(--lh-105-84);
  letter-spacing: var(--ls-tight-3);
  color: var(--c-white);
}

.h2 {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-62);
  font-weight: var(--fw-bold);
  line-height: var(--lh-63-24);
  letter-spacing: var(--ls-tight-2);
  color: var(--color-heading);
}

.h2--compact {
  font-size: var(--fs-54);
  line-height: var(--lh-56-16);
  letter-spacing: var(--ls-tight-1);
  color: var(--c-white);
}

.h3 {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-24);
  font-weight: var(--fw-bold);
  line-height: var(--lh-32);
  color: var(--color-heading-strong);
}

.prose {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--prose-gap);
  max-width: var(--measure-760);
}

.prose p {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-17);
  line-height: var(--lh-28);
  color: var(--color-body);
}

.prose--dark p {
  color: var(--color-heading-strong);
}

/* 1331:68667 and the three teaser leads set a span or two in the semibold and
   darken it with the weight. */
.prose strong,
.lead strong {
  font-weight: var(--fw-bold);
  color: var(--color-heading);
}

.lead {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-17);
  line-height: var(--lh-28);
  color: var(--color-body);
}

/* Set in the same regular weight as the copy Figma draws it in; only colour differs. */
.link-inline {
  color: var(--color-link);
  font-weight: var(--fw-regular);
  text-decoration: none;
  border-bottom: var(--bw-1) solid transparent;
  transition: border-color var(--t-fast), color var(--t-fast);
}

.link-inline:hover,
.link-inline:focus-visible {
  border-bottom-color: currentColor;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-14);
  border: 0;
  border-radius: var(--radius-0);
  font-family: var(--font-sans);
  font-weight: var(--fw-bold);
  line-height: normal;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--t-base), color var(--t-base),
    border-color var(--t-base), transform var(--t-base);
}

.btn__arrow {
  font-family: var(--font-arrow);
  font-weight: var(--fw-bold);
  transition: transform var(--t-base);
}

.btn:hover .btn__arrow {
  transform: translateX(4px);
}

.btn--hero {
  padding: var(--sp-16) 30px;
  font-size: var(--fs-16);
  background: var(--c-white);
  color: var(--color-heading);
}

.btn--hero:hover {
  background: var(--color-on-dark);
}

.btn--underline {
  padding: 0 0 var(--sp-13);
  font-size: var(--fs-16);
  color: var(--c-white);
  border-bottom: var(--bw-3) solid var(--color-accent);
}

.btn--underline:hover {
  color: var(--color-accent);
}

.btn--primary {
  padding: var(--sp-14) 26px;
  font-size: var(--fs-15);
  background: var(--color-heading);
  color: var(--c-white);
}

.btn--primary:hover {
  background: var(--c-cyan-15);
}

/* 13/26 rather than 14/27: the 1px rule is part of the Figma link's 135x46 box,
   so it has to come out of the padding or the button outgrows its twin. */
.btn--secondary {
  padding: var(--sp-13) 26px;
  font-size: var(--fs-15);
  background: var(--c-white);
  color: var(--color-heading);
  border: var(--bw-1) solid var(--color-heading);
}

.btn--secondary:hover {
  background: var(--bg-page-alt);
}

.btn--accent {
  padding: var(--sp-16) var(--sp-34);
  font-size: var(--fs-16);
  background: var(--color-accent);
  color: var(--c-white);
}

/* Figma "Lg Green Button" 612:1411 — the hover variant (612:1412) inverts the button
   rather than darkening it: accent fill to Catskill White, label to Black Pearl. */
.btn--accent:hover:not(:disabled) {
  background: var(--c-grey-93);
  color: var(--c-cyan-6);
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.btn--nav {
  padding: var(--sp-9) var(--sp-18);
  font-family: var(--font-mono);
  font-size: var(--fs-11-5);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide-161);
  text-transform: uppercase;
  background: var(--color-accent);
  color: var(--c-white);
}

/* Figma "Med Green button" 612:1229 — hover inverts the pill the same way, on
   Catskill White rather than the step-lighter grey the mailing-list button uses. */
.btn--nav:hover {
  background: var(--c-grey-95);
  color: var(--c-cyan-6);
}

.cta-row {
  display: flex;
  align-items: center;
  gap: var(--sp-28);
  width: 100%;
  padding-top: var(--sp-33);
  border-top: var(--bw-1) solid var(--border-rule);
}

/* Bordered list — shared by the transition steps and the background timeline. */

.rule-list {
  width: 100%;
  border: var(--bw-1) solid var(--border-rule-strong);
}

.rule-list--faint {
  border-color: var(--border-rule);
}

.rule-list__item {
  display: flex;
  align-items: flex-start;
}

.rule-list__item + .rule-list__item {
  border-top: var(--bw-1) solid var(--border-rule-strong);
}

.rule-list--faint .rule-list__item + .rule-list__item {
  border-top-color: var(--border-rule);
}

/* The <label> is the field box itself, so the whole 2px-ruled area is a hit
   target for its input and no for/id pairing is needed. */
.field {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  padding: var(--sp-12) 2px var(--sp-14);
  border-bottom: var(--bw-2) solid var(--color-muted);
  transition: border-color var(--t-base), background-color var(--t-base);
}

/* Figma 315:1973 — a focused field fills its whole box white; the box is the
   <label>, so the fill covers the field and not just the input. */
.field:focus-within {
  padding-left: var(--sp-10);
  background: var(--c-white);
  border-bottom-color: var(--color-accent);
}

.field__input {
  width: 100%;
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-16);
  font-weight: var(--fw-regular);
  line-height: normal;
  color: var(--c-white);
  background: transparent;
  border: 0;
  border-radius: var(--radius-0);
  appearance: none;
}

/* White text reads on the deep teal surface, not on the focused field's white fill:
   what is typed switches to the body colour there. */
.field:focus-within .field__input {
  color: var(--color-body);
}

.field__input::placeholder {
  color: var(--color-muted);
  opacity: 1;
}

/* Autofill repaints the input with a pale blue UA background, which breaks 315:1973.
   `background` cannot override the UA rule, so the surface is painted with an inset
   shadow instead, and the long transition delay keeps Chrome from animating to blue. */
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover,
.field__input:-webkit-autofill:focus,
.field__input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--c-white);
  caret-color: var(--c-white);
  box-shadow: inset 0 0 0 100px var(--bg-deep);
  transition: background-color 0s 600000s, color 0s 600000s;
}

.field:focus-within .field__input:-webkit-autofill,
.field:focus-within .field__input:-webkit-autofill:hover,
.field:focus-within .field__input:-webkit-autofill:focus,
.field:focus-within .field__input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--color-body);
  caret-color: var(--color-body);
  box-shadow: inset 0 0 0 100px var(--c-white);
}

/* Same repaint for the standard selector (Firefox, Safari 16.4+). Its own rule:
   browsers without `:autofill` would drop a merged selector list entirely. */
.field__input:autofill {
  -webkit-text-fill-color: var(--c-white);
  caret-color: var(--c-white);
  box-shadow: inset 0 0 0 100px var(--bg-deep);
}

.field:focus-within .field__input:autofill {
  -webkit-text-fill-color: var(--color-body);
  caret-color: var(--color-body);
  box-shadow: inset 0 0 0 100px var(--c-white);
}

.field__input:focus {
  outline: none;
}

.field__input:focus-visible {
  outline: none;
}

/*
 * 1772:24824 — the same field on white. Everything the section form does to sit on
 * deep teal is undone: the rule is 1px rather than 2, the ink is body colour rather
 * than white, and focus has no fill to add because the surface is already white.
 */
.field--light {
  /* The caption sits inside this top padding rather than above the field, so
     revealing it on focus moves nothing around it. */
  position: relative;
  padding: var(--sp-19) var(--sp-2) var(--sp-12);
  border-bottom-width: var(--bw-1);
  border-bottom-color: var(--border-rule-strong);
}

/* The base rule shifts the text 8px right to make room for its fill. This fill is
   the whole box, so the field must not move under the cursor. */
.field--light:focus-within {
  padding-left: var(--sp-2);
  background: var(--c-grey-93);
  border-bottom-color: var(--color-accent);
}

/*
 * Visually hidden until the field has focus, and never hidden from a screen reader:
 * this is the input's accessible name whether or not it is on screen. The clip-path
 * technique matches .u-visually-hidden, which is what it behaves as when idle.
 */
.field__caption {
  position: absolute;
  top: var(--sp-4);
  left: var(--sp-2);
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  font-family: var(--font-sans);
  font-size: var(--fs-11);
  line-height: var(--lh-16);
  color: var(--color-body);
  opacity: 0;
  transition: opacity var(--t-fast);
}

.field--light:focus-within .field__caption {
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  opacity: 1;
}

/* The placeholder swaps to the field's hint on focus (js/register.js), which drops
   the asterisk with it — so the caption carries the requirement instead. */
.field--required .field__caption::after {
  content: ' *';
}

/* The field and whatever is said about it. This is what a row lays out, so a message
   appearing under one field pushes nothing sideways and does not move its neighbour. */
.field-group {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  min-width: 0;
}

/*
 * A rejected field's own message, under its rule rather than in the form's status line
 * — near the thing the visitor has to change. The frame draws no error state for these
 * fields, so this borrows the treatment the mailing list's status line already uses for
 * one: the site has no red, and says "wrong" with the accent rule instead.
 */
.field__error {
  margin: var(--sp-8) 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-11);
  line-height: var(--lh-16);
  letter-spacing: var(--ls-wide-1);
  color: var(--color-link);
}

.field__error[hidden] {
  display: none;
}

/* Holds the focused rule after focus has gone, so the field still reads as the one at
   fault once the visitor has moved on to fix it. */
.field--invalid,
.field--invalid:focus-within {
  border-bottom-color: var(--color-accent);
  border-bottom-width: var(--bw-2);
}

.field--light .field__input {
  font-size: var(--fs-15);
  color: var(--color-body);
}

.field--light .field__input::placeholder {
  color: var(--c-cyan-56);
}

/* Without these the base's autofill repaint would paint the modal's fields in the
   deep teal of the section form. Same two selectors, for the same reason. */
.field--light .field__input:-webkit-autofill,
.field--light .field__input:-webkit-autofill:hover,
.field--light .field__input:-webkit-autofill:focus,
.field--light .field__input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--color-body);
  caret-color: var(--color-body);
  box-shadow: inset 0 0 0 100px var(--c-white);
}

.field--light .field__input:autofill {
  -webkit-text-fill-color: var(--color-body);
  caret-color: var(--color-body);
  box-shadow: inset 0 0 0 100px var(--c-white);
}
