/* ==========================================================================
   KL Trains — site styles

   Every token here is lifted from the app's own design system, so the site
   and the app are the same object seen twice:

     Palette.swift     surfaces, ink, text ramp, rules, the platform sign
     Typography.swift  Helvetica Neue throughout, 10/600/.16em micro labels
     Components.swift  lozenge 54x23 r6, rail 4pt, cards square-edged on a
                       12pt band of paper, journey bar 26pt r4
     RailNetwork.swift the nine operator hexes, and the derived variants that
                       were each solved for a contrast ratio rather than eyed

   The app's cards have no corner radius: they are full-bleed slabs held apart
   by bands of page. That is kept here — it is what makes the thing read as
   printed signage rather than as a stack of app chrome.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Surfaces */
  --paper: #f4f3f0;
  --card: #ffffff;
  --ink: #111315;
  --on-ink: #ffffff;
  --on-ink-fill: rgba(255, 255, 255, 0.07);
  --on-ink-rule: rgba(255, 255, 255, 0.14);
  --on-ink-control: rgba(255, 255, 255, 0.55);
  --on-ink-control-off: rgba(255, 255, 255, 0.24);

  /* The primary action. Cannot reuse ink/paper — both are dark in dark mode. */
  --action-fill: #111315;
  --action-text: #f4f3f0;

  /* Type ramp */
  --text-primary: #111315;
  --text-secondary: #4b4f54;
  --text-tertiary: #63686d;
  --text-faint: #a2a6ab;
  /* Site-only. The app reserves `textFaint` for glyphs and empty states;
     here the same slot carries readable copy — help-index hints, 10px
     micro labels, list markers — so it is solved for 4.5:1 instead. */
  --text-hint: #63686d;

  /* Rules and texture */
  --hairline: rgba(17, 19, 21, 0.1);
  --rule: rgba(17, 19, 21, 0.18);
  --hatch: #cfccc6;
  --dash-rail: #c6c9cd;

  /* Platform sign */
  --badge: #0e5c2c;
  --sign-fill: #14539a;
  --sign-ink: #14539a;

  /* Line fills — the operators' own, straight from routes.txt. Used exactly
     as published wherever they are a fill behind a code. */
  --kajang: #047940;
  --putrajaya: #ffcd00;
  --kelana-jaya: #d50032;
  --ampang: #e57200;
  --sri-petaling: #76232f;
  --shah-alam: #00a9e0;
  --monorail: #84bd00;
  --komuter-pk: #dc2420;
  --komuter-sb: #3c5a9f;

  /* Line names, small tracked caps: solved for 4.5:1 against the page.
     Putrajaya and Monorail have to darken on paper to be readable at all. */
  --kajang-text: #047940;
  --putrajaya-text: #876d00;
  --kelana-jaya-text: #d50032;
  --ampang-text: #ae5700;
  --sri-petaling-text: #76232f;
  --shah-alam-text: #00789f;
  --monorail-text: #547900;
  --komuter-pk-text: #d8231f;
  --komuter-sb-text: #3c5a9f;

  /* The rail: 3:1 on paper, 4:1 on the dark page. */
  --kajang-rail: #047940;
  --putrajaya-rail: #a88700;
  --kelana-jaya-rail: #d50032;
  --ampang-rail: #dc6d00;
  --sri-petaling-rail: #76232f;
  --shah-alam-rail: #0096c7;
  --monorail-rail: #6b9900;
  --komuter-pk-rail: #dc2420;
  --komuter-sb-rail: #3c5a9f;

  /* Geometry, from Metrics */
  --code-column: 54px;
  --gutter: 14px;
  --content-inset: 68px;
  --lozenge-height: 23px;
  --lozenge-radius: 6px;
  --rail-width: 4px;
  --panel-radius: 12px;
  --card-gap: 12px;

  /* Page measure */
  --measure: 68rem;
  --measure-prose: 40rem;
  --edge: 28px;

  --font: "Helvetica Neue", HelveticaNeue, Helvetica, Arial, "Liberation Sans",
    sans-serif;
}

/* Dark is derived — the design doc is light-only. The rule: the plate stays
   the darkest element in both, so it keeps reading as signage rather than
   flipping to an elevated card. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #1c1f22;
    --card: #2a2e33;
    --ink: #0b0c0d;
    --on-ink: #f2f1ee;
    --on-ink-control: rgba(255, 255, 255, 0.48);
    --on-ink-control-off: rgba(255, 255, 255, 0.2);

    --action-fill: #f2f1ee;
    --action-text: #0b0c0d;

    --text-primary: #f2f1ee;
    --text-secondary: #b4b8bd;
    --text-tertiary: #8e9398;
    --text-faint: #63686d;
    --text-hint: #949a9f;

    --hairline: rgba(242, 241, 238, 0.13);
    --rule: rgba(242, 241, 238, 0.24);
    --hatch: #3e4145;
    --dash-rail: #4a4e52;

    --badge: #4fd183;
    --sign-fill: #1e63b5;
    --sign-ink: #8fbef0;

    --kajang-text: #059750;
    --putrajaya-text: #ffcd00;
    --kelana-jaya-text: #ff033e;
    --ampang-text: #e57200;
    --sri-petaling-text: #cf5d6d;
    --shah-alam-text: #00a9e0;
    --monorail-text: #84bd00;
    --komuter-pk-text: #e44a46;
    --komuter-sb-text: #6380c4;

    --kajang-rail: #058c4a;
    --putrajaya-rail: #ffcd00;
    --kelana-jaya-rail: #f00038;
    --ampang-rail: #e57200;
    --sri-petaling-rail: #cb4f61;
    --shah-alam-rail: #00a9e0;
    --monorail-rail: #84bd00;
    --komuter-pk-rail: #e13430;
    --komuter-sb-rail: #5676bf;
  }
}

/* --------------------------------------------------------------------------
   Reset and base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
svg {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--sign-fill);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Skip link — the site's own dead-end guard. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--action-fill);
  color: var(--action-text);
  padding: 12px 20px;
  font-size: 14px;
}
.skip:focus {
  left: 12px;
  top: 12px;
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.25rem, 6.2vw, 4rem);
}
h2 {
  font-size: clamp(1.6rem, 3.6vw, 2.35rem);
}
h3 {
  font-size: 1.25rem;
  letter-spacing: -0.01em;
}
h4 {
  font-size: 1.0625rem;
  letter-spacing: -0.005em;
}

p {
  margin: 0 0 1em;
}
p:last-child {
  margin-bottom: 0;
}

/* The 10/600/.16em uppercase label used throughout both designs. */
.micro {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--text-hint);
}
.micro--on-ink {
  color: var(--on-ink-control);
}

/* Figures: Helvetica Bold held to tabular widths so they do not jitter. */
.figure {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.02em;
}

.lede {
  font-size: clamp(1.0625rem, 1.9vw, 1.3125rem);
  line-height: 1.5;
  color: var(--text-secondary);
  text-wrap: pretty;
}

.quiet {
  color: var(--text-tertiary);
  font-size: 0.9375rem;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

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

.wrap--prose {
  max-width: calc(var(--measure-prose) + var(--edge) * 2);
}

section {
  padding-block: clamp(56px, 8vw, 96px);
}

.section-head {
  max-width: 46rem;
  margin-bottom: clamp(32px, 4vw, 48px);
}
.section-head .micro {
  margin-bottom: 14px;
}
.section-head p {
  margin-top: 16px;
  color: var(--text-secondary);
  font-size: 1.0625rem;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   The plate

   Mounted above everything, the way JourneyHeader is mounted above the
   navigation stack rather than inside it. It is the same ink in the site
   header as in the app, and it stays the darkest thing on the page.
   -------------------------------------------------------------------------- */

.plate {
  background: var(--ink);
  color: var(--on-ink);
}

.plate a {
  text-decoration: none;
}

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ink);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: 24px;
  min-height: 60px;
  padding-block: 12px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--on-ink);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark svg {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  flex: none;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-left: auto;
  font-size: 0.8125rem;
}
.nav__links a {
  color: var(--on-ink-control);
  transition: color 0.15s ease;
}
.nav__links a:hover,
.nav__links a[aria-current="page"] {
  color: var(--on-ink);
}

@media (max-width: 640px) {
  .nav__links {
    gap: 16px;
    font-size: 0.75rem;
  }
  .nav__links .nav__hide-sm {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  padding-top: clamp(40px, 6vw, 72px);
  padding-bottom: clamp(48px, 7vw, 88px);
}

.hero__grid {
  display: grid;
  gap: clamp(40px, 6vw, 72px);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
}

.hero h1 {
  color: var(--on-ink);
  margin-bottom: 22px;
}

.hero .lede {
  color: rgba(255, 255, 255, 0.72);
  max-width: 34rem;
}

.hero__eyebrow {
  margin-bottom: 20px;
  color: var(--on-ink-control);
}

.hero__cta {
  margin-top: 34px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
}

.hero__note {
  margin-top: 20px;
  font-size: 0.8125rem;
  color: rgba(255, 255, 255, 0.52);
}

/* --------------------------------------------------------------------------
   Buttons

   The primary action inverts against the page, not against ink — which is why
   it has its own token pair.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 26px;
  border: 0;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.btn:hover {
  opacity: 0.86;
}
.btn:active {
  transform: translateY(1px);
}

/* On the plate, the action inverts against the plate. */
.btn--primary {
  background: var(--on-ink);
  color: var(--ink);
}

/* On paper, it takes the app's own action pair. */
.btn--onpaper {
  background: var(--action-fill);
  color: var(--action-text);
}

.btn--ghost {
  background: transparent;
  color: var(--on-ink-control);
  border: 1px solid var(--on-ink-rule);
  padding-block: 13px;
}
.btn--ghost:hover {
  color: var(--on-ink);
  border-color: rgba(255, 255, 255, 0.3);
  opacity: 1;
}

/* --------------------------------------------------------------------------
   Journey rows — the plate's two ends, reproduced

   Both ends stay live in the app; here they are static, so they are marked
   aria-hidden and the surrounding copy carries the meaning.
   -------------------------------------------------------------------------- */

.journey {
  border: 1px solid var(--on-ink-rule);
  padding: 20px 22px;
}

.journey__row {
  display: grid;
  grid-template-columns: var(--code-column) var(--gutter) 1fr;
  align-items: center;
  padding-block: 12px;
}

.journey__row + .journey__row {
  border-top: 1px solid var(--on-ink-rule);
}

.lozenge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--code-column);
  height: var(--lozenge-height);
  border-radius: var(--lozenge-radius);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  line-height: 1;
  flex: none;
}

.journey__end {
  grid-column: 3;
  min-width: 0;
}
.journey__name {
  font-size: 18px;
  font-weight: 500;
  color: var(--on-ink);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.journey__label {
  margin-bottom: 3px;
}

.journey__measures {
  display: flex;
  gap: 28px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--on-ink-rule);
}
.journey__measure .micro {
  margin-bottom: 4px;
}
.journey__measure .figure {
  font-size: 26px;
  color: var(--on-ink);
  line-height: 1.1;
}
.journey__measure .figure span {
  font-size: 14px;
  font-weight: 400;
  color: var(--on-ink-control);
  margin-left: 2px;
}

/* --------------------------------------------------------------------------
   Cards

   Square-edged, full-bleed, held apart by a band of page. That band is the
   whole of what separates them, so it is set rather than left to a gap.
   -------------------------------------------------------------------------- */

.cards {
  display: grid;
  gap: var(--card-gap);
}

@media (min-width: 720px) {
  .cards--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .cards--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1000px) {
  .cards--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.card {
  background: var(--card);
  padding: 28px var(--edge);
}

.card h3 {
  margin-bottom: 10px;
}
.card p {
  color: var(--text-secondary);
  font-size: 0.9375rem;
  margin-bottom: 0;
  text-wrap: pretty;
}
.card .micro {
  margin-bottom: 16px;
}

/* --------------------------------------------------------------------------
   Numbered steps — the rail runs down the code column, as in the ledger
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  gap: 0;
  background: var(--card);
}

.step {
  display: grid;
  grid-template-columns: var(--code-column) var(--gutter) 1fr;
  padding: 26px var(--edge);
  position: relative;
}

.step + .step::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--content-inset);
  right: var(--edge);
  height: 1px;
  background: var(--hairline);
}

.step__mark {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--on-ink);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex: none;
}

.step__rail {
  width: var(--rail-width);
  flex: 1;
  min-height: 12px;
  background: var(--kajang-rail);
  border-radius: 2px;
}
.step:last-child .step__rail {
  display: none;
}

.step__body {
  grid-column: 3;
}
.step__body h3 {
  margin-bottom: 8px;
}
.step__body p {
  color: var(--text-secondary);
  font-size: 0.9375rem;
  margin-bottom: 0;
  text-wrap: pretty;
}

@media (max-width: 560px) {
  .step {
    grid-template-columns: 36px var(--gutter) 1fr;
    padding-inline: 20px;
  }
  .step + .step::before {
    left: 50px;
    right: 20px;
  }
}

/* --------------------------------------------------------------------------
   Journey bar — bar length is time, wherever one is drawn
   -------------------------------------------------------------------------- */

.bar {
  display: flex;
  height: 26px;
  border-radius: 4px;
  overflow: hidden;
  margin-block: 14px 10px;
}

.bar__leg {
  height: 100%;
  min-width: 10px;
}

/* A walk. Dashed rail rather than a fill — it is not a ride. */
.bar__walk {
  min-width: 10px;
  background-image: repeating-linear-gradient(
    -45deg,
    var(--hatch),
    var(--hatch) 2px,
    transparent 2px,
    transparent 5px
  );
  background-color: var(--paper);
}

/* --------------------------------------------------------------------------
   Platform sign — filled half is the platform, outlined half the direction
   -------------------------------------------------------------------------- */

.sign {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--sign-fill);
  font-size: 11.5px;
  line-height: 1.35;
  vertical-align: middle;
}
.sign__platform {
  background: var(--sign-fill);
  color: #fff;
  font-weight: 600;
  letter-spacing: 0.23px;
  padding: 5px 9px;
}
.sign__to {
  color: var(--sign-ink);
  font-weight: 500;
  padding: 5px 9px;
  background: var(--paper);
}
.card .sign__to {
  background: var(--card);
}

/* A value the app has assumed rather than been told. */
.assumed {
  border-bottom: 1px dashed currentColor;
  padding-bottom: 1px;
}

/* --------------------------------------------------------------------------
   The nine lines
   -------------------------------------------------------------------------- */

.lines {
  background: var(--card);
}

.line-row {
  display: grid;
  grid-template-columns: var(--code-column) var(--gutter) 1fr auto;
  align-items: center;
  gap: 0;
  padding: 16px var(--edge);
  position: relative;
}

.line-row + .line-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--content-inset);
  right: var(--edge);
  height: 1px;
  background: var(--hairline);
}

.line-row__name {
  grid-column: 3;
  min-width: 0;
}
.line-row__name strong {
  display: block;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-primary);
  letter-spacing: -0.005em;
}
.line-row__name .micro {
  margin-top: 3px;
}

.line-row__count {
  grid-column: 4;
  text-align: right;
  padding-left: 16px;
  white-space: nowrap;
}
.line-row__count .figure {
  font-size: 17px;
  color: var(--text-primary);
}
.line-row__count .micro {
  margin-top: 2px;
}

@media (max-width: 560px) {
  .line-row {
    padding-inline: 20px;
  }
  .line-row + .line-row::before {
    left: 88px;
    right: 20px;
  }
}

/* Per-line colour hooks. */
.l-kajang { background: var(--kajang); color: #fff; }
.l-putrajaya { background: var(--putrajaya); color: #111315; }
.l-kelana-jaya { background: var(--kelana-jaya); color: #fff; }
.l-ampang { background: var(--ampang); color: #111315; }
.l-sri-petaling { background: var(--sri-petaling); color: #fff; }
.l-shah-alam { background: var(--shah-alam); color: #111315; }
.l-monorail { background: var(--monorail); color: #111315; }
.l-komuter-pk { background: var(--komuter-pk); color: #fff; }
.l-komuter-sb { background: var(--komuter-sb); color: #fff; }

.t-kajang { color: var(--kajang-text); }
.t-putrajaya { color: var(--putrajaya-text); }
.t-kelana-jaya { color: var(--kelana-jaya-text); }
.t-ampang { color: var(--ampang-text); }
.t-sri-petaling { color: var(--sri-petaling-text); }
.t-shah-alam { color: var(--shah-alam-text); }
.t-monorail { color: var(--monorail-text); }
.t-komuter-pk { color: var(--komuter-pk-text); }
.t-komuter-sb { color: var(--komuter-sb-text); }

.b-kajang { background: var(--kajang-rail); }
.b-putrajaya { background: var(--putrajaya-rail); }
.b-kelana-jaya { background: var(--kelana-jaya-rail); }
.b-ampang { background: var(--ampang-rail); }
.b-sri-petaling { background: var(--sri-petaling-rail); }
.b-shah-alam { background: var(--shah-alam-rail); }
.b-monorail { background: var(--monorail-rail); }
.b-komuter-pk { background: var(--komuter-pk-rail); }
.b-komuter-sb { background: var(--komuter-sb-rail); }

/* --------------------------------------------------------------------------
   Ledger — station to station, on the two-column grid
   -------------------------------------------------------------------------- */

.ledger {
  background: var(--card);
  padding: 24px 0;
}

.ledger__row {
  display: grid;
  grid-template-columns: var(--code-column) var(--gutter) 1fr;
  padding: 0 var(--edge);
  position: relative;
  min-height: 44px;
}

.ledger__code {
  grid-column: 1;
  grid-row: 1;
  z-index: 1;
  padding-top: 10px;
}

/* The rail running down the centre of the code column. */
.ledger__row::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--edge) + 27px - var(--rail-width) / 2);
  width: var(--rail-width);
  background: var(--rail-colour, var(--dash-rail));
}
.ledger__row--first::before {
  top: 21px;
}
.ledger__row--last::before {
  bottom: calc(100% - 21px);
}
.ledger__row--walk::before {
  background: none;
  border-left: var(--rail-width) dashed var(--dash-rail);
  width: 0;
}

.ledger__body {
  grid-column: 3;
  padding: 8px 0 14px;
}
.ledger__station {
  font-size: 18px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.25;
}
.ledger__station--small {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-tertiary);
}
.ledger__detail {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.ledger__note {
  font-size: 13px;
  color: var(--text-tertiary);
}

@media (max-width: 560px) {
  .ledger__row {
    padding-inline: 20px;
  }
  .ledger__row::before {
    left: calc(20px + 27px - var(--rail-width) / 2);
  }
}

/* --------------------------------------------------------------------------
   Prose — the policy pages
   -------------------------------------------------------------------------- */

.prose {
  font-size: 1.0625rem;
  line-height: 1.68;
  color: var(--text-secondary);
}

.prose h2 {
  font-size: 1.375rem;
  color: var(--text-primary);
  margin: 48px 0 14px;
  scroll-margin-top: 84px;
}
.prose h2:first-child {
  margin-top: 0;
}

.prose h3 {
  font-size: 1.0625rem;
  color: var(--text-primary);
  margin: 30px 0 10px;
}

.prose p {
  margin: 0 0 1.1em;
  text-wrap: pretty;
}

.prose ul,
.prose ol {
  margin: 0 0 1.3em;
  padding-left: 1.35em;
}
.prose li {
  margin-bottom: 0.55em;
}
.prose li::marker {
  color: var(--text-hint);
}

.prose strong {
  color: var(--text-primary);
  font-weight: 500;
}

.prose a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--rule);
  text-decoration-thickness: 1px;
}
.prose a:hover {
  text-decoration-color: currentColor;
}

.prose code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 0.875em;
  background: var(--card);
  padding: 1px 5px;
  border-radius: 3px;
}

/* A pulled-out note, set on card so it lifts off the page. */
.note {
  background: var(--card);
  padding: 22px var(--edge);
  margin: 28px 0;
  font-size: 0.9375rem;
  color: var(--text-secondary);
  border-left: var(--rail-width) solid var(--kajang-rail);
}
.note .micro {
  margin-bottom: 8px;
}
.note p:last-child {
  margin-bottom: 0;
}

/* The dated header on a policy page. */
.doc-head {
  padding-top: clamp(40px, 5vw, 64px);
  padding-bottom: clamp(28px, 3.5vw, 40px);
}
.doc-head h1 {
  font-size: clamp(2rem, 4.6vw, 3rem);
  color: var(--on-ink);
  margin-bottom: 16px;
}
.doc-head .lede {
  color: rgba(255, 255, 255, 0.66);
  max-width: 38rem;
}
.doc-head .micro {
  color: var(--on-ink-control);
  margin-bottom: 18px;
}
.doc-head__dates {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--on-ink-rule);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 32px;
}
.doc-head__dates div .micro {
  margin-bottom: 3px;
}
.doc-head__dates div span {
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.8);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   FAQ / disclosure
   -------------------------------------------------------------------------- */

.faq {
  background: var(--card);
}

.faq details {
  border-top: 1px solid var(--hairline);
}
.faq details:first-of-type {
  border-top: 0;
}

.faq summary {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 22px var(--edge);
  cursor: pointer;
  list-style: none;
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--text-primary);
  letter-spacing: -0.005em;
}
.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "";
  margin-left: auto;
  margin-top: 7px;
  width: 9px;
  height: 9px;
  flex: none;
  border-right: 1.5px solid var(--text-hint);
  border-bottom: 1.5px solid var(--text-hint);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}
.faq details[open] summary::after {
  transform: rotate(-135deg);
  margin-top: 11px;
}

.faq__answer {
  padding: 0 var(--edge) 24px;
  max-width: 46rem;
  color: var(--text-secondary);
  font-size: 0.9375rem;
  line-height: 1.65;
}
.faq__answer p {
  margin-bottom: 0.9em;
}

/* --------------------------------------------------------------------------
   Help index
   -------------------------------------------------------------------------- */

.help-index {
  background: var(--card);
  display: grid;
}

.help-index a {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 16px;
  padding: 18px var(--edge);
  text-decoration: none;
  color: var(--text-primary);
  font-size: 0.9375rem;
  border-top: 1px solid var(--hairline);
  transition: background 0.12s ease;
}
.help-index a:first-child {
  border-top: 0;
}
.help-index a:hover {
  background: var(--paper);
}
.help-index a span {
  color: var(--text-hint);
  font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   Contact block
   -------------------------------------------------------------------------- */

.contact {
  background: var(--ink);
  color: var(--on-ink);
  padding: clamp(32px, 4.5vw, 48px) var(--edge);
}
.contact h2 {
  color: var(--on-ink);
  margin-bottom: 14px;
}
.contact p {
  color: rgba(255, 255, 255, 0.68);
  max-width: 40rem;
  font-size: 1rem;
}
.contact a {
  color: var(--on-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(255, 255, 255, 0.35);
}
.contact a:hover {
  text-decoration-color: currentColor;
}
.contact .micro {
  color: var(--on-ink-control);
  margin-bottom: 14px;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer {
  background: var(--ink);
  color: var(--on-ink-control);
  padding-block: clamp(40px, 5vw, 60px);
  font-size: 0.875rem;
}

.footer__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 48px;
  justify-content: space-between;
  align-items: flex-start;
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer__links a {
  color: var(--on-ink-control);
  text-decoration: none;
  transition: color 0.15s ease;
}
.footer__links a:hover {
  color: var(--on-ink);
}

.footer__brand p {
  margin-top: 12px;
  max-width: 26rem;
  color: rgba(255, 255, 255, 0.52);
  font-size: 0.8125rem;
  line-height: 1.6;
}

.footer__legal {
  margin-top: 36px;
  padding-top: 24px;
  border-top: 1px solid var(--on-ink-rule);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  justify-content: space-between;
  color: rgba(255, 255, 255, 0.52);
  font-size: 0.8125rem;
}
.footer__legal a {
  color: inherit;
}
.footer__legal a:hover {
  color: var(--on-ink);
}

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.stack-sm > * + * {
  margin-top: 8px;
}
.mt-lg {
  margin-top: clamp(32px, 4vw, 48px);
}
.center {
  text-align: center;
}
.nowrap {
  white-space: nowrap;
}

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

/* A full-bleed band of card that runs edge to edge on the page. */
.bleed {
  background: var(--card);
}

/* --------------------------------------------------------------------------
   Screen mock

   A representation of the app, built out of the same tokens as the app rather
   than pasted in as a picture — so it tracks the reader's appearance setting
   and stays sharp at any size. It is decorative: the copy beside it carries
   the meaning, and the mock itself is hidden from assistive technology.
   -------------------------------------------------------------------------- */

.screen {
  max-width: 400px;
  margin-inline: auto;
  background: var(--paper);
  border: 1px solid var(--on-ink-rule);
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 30px 70px -24px rgba(0, 0, 0, 0.55);
}

.screen__plate {
  background: var(--ink);
  padding: 22px 22px 18px;
}

.screen__body {
  padding: var(--card-gap) 0 0;
  display: grid;
  gap: var(--card-gap);
}

.screen__card {
  background: var(--card);
  padding: 18px 22px;
}

.screen__card .micro {
  margin-bottom: 10px;
}

/* Inside a mock the journey rows lose their outer border — the plate is
   already the boundary. */
.screen__plate .journey {
  border: 0;
  padding: 0;
}

.route-row__top {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.route-row__top .figure {
  font-size: 34px;
  line-height: 1;
  color: var(--text-primary);
}
.route-row__top .unit {
  font-size: 15px;
  color: var(--text-tertiary);
}
.route-row__top .changes {
  margin-left: auto;
  font-size: 13px;
  color: var(--text-tertiary);
}
.route-row__via {
  font-size: 13px;
  color: var(--text-tertiary);
  text-wrap: pretty;
}

/* Bar length is time. The track is a percentage of the longest route on show,
   so a short journey draws short beside a long one. */
.bar__track {
  display: flex;
  height: 26px;
  border-radius: 4px;
  overflow: hidden;
}

/* Two columns of topics once there is room for them. */
@media (min-width: 760px) {
  .help-index {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .help-index a:nth-child(2) {
    border-top: 0;
  }
  /* An odd number of topics leaves the last cell without a neighbour, and a
     rule down the side of nothing reads as an unfinished table. */
  .help-index a:nth-child(odd):not(:last-child) {
    border-right: 1px solid var(--hairline);
  }
}

/* On a narrow screen the two hero actions stack. Left-aligned buttons of
   unequal width read as ragged once they are on separate lines, so they take
   the full measure and centre their labels. */
@media (max-width: 540px) {
  .hero__cta {
    display: grid;
    gap: 12px;
  }
  .btn {
    justify-content: center;
  }
}

/* A note and an inline code span both lift off the page by taking the *other*
   surface. On a paper section that is the card; on a card section it has to
   invert, or the pulled-out block disappears into the ground it sits on.
   The platform sign's outlined half stays paper either way — on the app it is
   the page showing through, which is what makes it read as outlined. */
.bleed .note,
.bleed .prose code {
  background: var(--paper);
}
