/* ============================================================================
   KSRTC DESIGN SYSTEM — COMPONENT LAYER
   design-system/components.css
   ----------------------------------------------------------------------------
   Owns every block named in docs/DESIGN-SYSTEM.md's class contract, and nothing
   else. base.css owns the reset, document typography, the Malayalam guards, the
   two-tone :focus-visible ring, .u-skip, .u-visually-hidden, .u-wrap,
   .u-measure, .u-bi and .u-bii — none of those are redefined in this file.

   THE ONE HARD RULE
   -----------------
   There is not a single hex, rgb(), hsl() or named colour in this file. Every
   colour resolves to a semantic token from tokens.css. Where translucency is
   needed it is written as

       color-mix(in srgb, var(--token) N%, transparent)

   so it stays theme-derived: swap the theme and the wash swaps with it. A
   hard-coded colour would silently break the other three themes, which is the
   single most expensive defect available in this codebase.

   THE FOUR THEMES ARE NOT COSMETIC — they change geometry as well as hue:
     --radius     0 (yathra) → 2px (livery) → 4px (ticket) → 16/22px (thaneer)
     --shadow     none (livery, yathra) → hard 1px (ticket) → soft stack (thaneer)
     --rule-w     1px hairline everywhere, --rule-w-strong 2-3px
     --divider    livery-sweep / wave / route-line / perforation

   Therefore: NOTHING in this file uses a shadow as the only thing separating a
   card from its background. Structure is carried by --rule / --rule-w, and
   --shadow is layered on top purely as an enhancement. Verified at --radius:0
   and --radius-lg:22px.

   RESPONSIVENESS
   --------------
   No fixed breakpoints anywhere (tender Clause 2.3 forbids a fixed grid). Every
   layout is either flex-wrap with a min(100%, …) basis, or
   repeat(auto-fit, minmax(min(100%, clamp(…)), 1fr)) — the clamp() inside the
   minmax() is what produces breakpoint-like column counts fluidly, with no
   media query and no jump.

   MALAYALAM
   ---------
   --fs-small (15px) is the floor for anything containing Malayalam.
   --fs-micro is LATIN ONLY and is therefore only ever applied through an
   [lang="en"] selector. letter-spacing likewise: every tracking rule in this
   file is scoped to [lang="en"], because tracking breaks Malayalam conjunct
   joins. Multi-line Malayalam body copy keeps --lh-body (1.75).

   Section map
     1  shared component internals (button shell, chips, icons)
     2  .c-utilitybar
     3  .c-masthead / .c-nav
     4  .c-hero
     5  .c-search
     6  .c-band / .c-sechead / section dividers
     7  .c-tasks
     8  .c-notices / .c-notice
     9  .c-fares
    10  .c-dest
    11  .c-stat
    12  .c-footer / .c-appblock / .c-social / .c-staff / .c-legal
    13  optional modules: .u-perforate, .network-diagram
    14  reduced-motion backstop
   ========================================================================== */


/* ══ 1 · SHARED COMPONENT INTERNALS ═══════════════════════════════════════ */

/* ── The "on a dark or coloured surface" token re-point ────────────────────
   Instead of every component knowing whether it sits on cream or on the dark
   band, the CONTAINER re-points the ink tokens once and every descendant reads
   the right colour automatically. This is the whole reason the theme switch is
   cheap: add a component and it inherits correct contrast for free.

   Contrast note on the accent (red) band: --ink-on-accent is only 5.01:1 on
   livery's --surface-accent, so a translucent "secondary" ink would drop below
   AA (measured 3.85:1 at 84%, 4.38:1 at 92%). --ink-2 is therefore held at full
   strength there and secondary text is distinguished by size and weight
   instead. Never by colour alone in any case. */
.c-utilitybar,
.c-hero,
.c-band--invert,
.c-footer {
  --ink: var(--ink-invert);
  --ink-2: color-mix(in srgb, var(--ink-invert) 78%, transparent);   /* 9.5:1 */
  --surface-3: color-mix(in srgb, var(--ink-invert) 8%, var(--surface-invert));
  --rule: color-mix(in srgb, var(--ink-invert) 26%, transparent);
  --rule-strong: var(--highlight);
  /* --highlight is a FILL/RULE colour, not a text colour. Using it here measured
     4.33:1 at 15px in the yathra theme, whose --highlight is orange rather than gold.
     --accent-on-invert is the text-safe accent for inverted surfaces. */
  --accent-text: var(--accent-on-invert);
  --accent-strong: var(--accent-on-invert);
  color: var(--ink);
}

.c-band--accent {
  --ink: var(--ink-on-accent);
  --ink-2: var(--ink-on-accent);            /* full strength — see note above */
  /* A raised card on the red band is DARKENED, not lightened. Lightening it
     measured 4.21:1 for --ink-on-accent in livery (below AA); darkening with
     --surface-invert measures 6.28:1. */
  --surface-3: color-mix(in srgb, var(--surface-invert) 18%, var(--surface-accent));
  --rule: color-mix(in srgb, var(--ink-on-accent) 40%, transparent);
  --rule-strong: var(--ink-on-accent);
  --accent: var(--highlight);               /* red-on-red rules are invisible */
  --accent-text: var(--ink-on-accent);
  --accent-strong: var(--ink-on-accent);
  color: var(--ink);
}

/* ── Button shell ─────────────────────────────────────────────────────────
   One shell, reached through the contract's own class names — no invented
   public .c-btn class. min-height is --tap (44px) plus padding, so every one of
   these clears WCAG 2.5.5 at every text size. */
.c-hero__cta > a,
.c-search__submit,
.c-search__book,
.c-appblock__badge,
.c-notices__more > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-5);
  border: var(--rule-w) solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 650;
  line-height: var(--lh-display);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.c-hero__cta > a > svg,
.c-search__submit > svg,
.c-search__book > svg,
.c-appblock__badge > svg {
  flex: 0 0 auto;
  width: 1.375em;
  height: 1.375em;
}

/* Primary — gold plate. The type colour is --surface-invert, NOT --ink: --ink is
   re-pointed to a light value inside .c-hero and any inverted band, which would
   put light type on a gold plate. --surface-invert is dark in all four themes,
   so this pair is stable wherever the button is placed.
   Measured: --surface-invert on --highlight is 12.75:1 in livery / thaneer /
   ticket and 5.42:1 in yathra, where --highlight is the brand orange. */
.c-hero__cta > a:first-child,
.c-search__submit {
  background: var(--highlight);
  color: var(--surface-invert);
  border-color: color-mix(in srgb, var(--surface-invert) 25%, transparent);
}

/* ── DO NOT LET --shadow EAT THE FOCUS RING ───────────────────────────────
   base.css draws the focus ring as `outline` PLUS a two-band `box-shadow`.
   components.css loads after base.css, so a component's own
   `box-shadow: var(--shadow)` has equal specificity to `:focus-visible` and
   would silently win on focus — leaving one band where three were certified.
   Every component that paints a shadow AND can take focus therefore scopes
   that shadow to :not(:focus-visible). This is the same class of defect as the
   gold-ring-on-a-red-button one: a ring that measures fine in isolation and is
   destroyed by the cascade. */
.c-hero__cta > a:first-child:not(:focus-visible),
.c-search__submit:not(:focus-visible),
.c-tasks__item:not(:focus-visible),
.c-dest__card:not(:focus-visible) { box-shadow: var(--shadow); }
/* Secondary — outlined, reads on cream and on the scrim alike, because --ink
   follows the band it is sitting in. */
.c-search__book,
.c-notices__more > a {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink);
  border-color: var(--ink);
  border-width: var(--rule-w-strong);
}
@media (hover: hover) {
  .c-hero__cta > a:hover,
  .c-search__submit:hover,
  .c-search__book:hover,
  .c-appblock__badge:hover,
  .c-notices__more > a:hover { transform: translateY(-2px); }
  .c-search__book:hover,
  .c-notices__more > a:hover {
    background: color-mix(in srgb, var(--ink) 16%, transparent);
  }
}

/* ── Chip: a small labelled tag. Always carries a word, never colour alone.
   line-height is --lh-body, not --lh-display: a chip lives inside a <p>, so if
   its Malayalam ever wraps to two lines it must still clear the 1.7 floor. */
.c-notice__chip,
.c-dest__tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-small);
  font-weight: 650;
  line-height: var(--lh-body);
}
.c-notice__chip > svg,
.c-dest__tag > svg { width: 1.15em; height: 1.15em; flex: 0 0 auto; }

/* ── Sample-content badge. Illustrative copy is always visibly marked.
   These three elements are themselves [lang="en"], which is the only reason the
   micro size and the tracking are allowed. The tracking is deliberately NOT set
   on any container, so no Malayalam sibling can ever inherit it. */
.c-notice__sample,
.c-appblock__sample,
.c-search__sample {
  font-family: var(--font-en);
  font-size: var(--fs-micro);        /* Latin only — the badge word is English */
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: inline-block;
  padding: 0.15em 0.5em;
  border-radius: var(--radius);
  /* A sample badge is a CHIP: it appears on cream, on the red accent band and inside the
     dark footer, so it must not inherit its contrast from whatever it happens to sit on.
     It previously used a 26%-alpha --highlight tint with --accent-strong text, which in
     the .c-band--accent context resolves to near-white --ink-on-accent over a LIGHTENED
     red — measured 4.29:1 in livery, under the 4.5 floor.
     Now fully OPAQUE: --highlight as a fill (permitted for fills, never for text) with
     dark --surface-invert text on top. That pairing is self-contained and clears AA on
     every ground in every theme. */
  background: var(--highlight);
  color: var(--surface-invert);
  border: var(--rule-w) solid color-mix(in srgb, var(--surface-invert) 35%, var(--highlight));
  white-space: nowrap;
}

/* ── The parallel English line in RUNNING PROSE ───────────────────────────
   base.css's .u-bi / .u-bii track and uppercase the parallel line. That is right
   for a label, a nav item or a statistic, and wrong for a sentence: a tracked
   all-caps standfirst reads as a second heading and is markedly harder to scan.
   Every prose context on this page therefore keeps its English at the 15px floor
   in sentence case. Tracking stays scoped to [lang="en"] either way, so no
   Malayalam is ever touched. */
.c-hero__standfirst [lang="en"],
.c-sechead p [lang="en"],
.c-search__hint [lang="en"],
.c-fares__note [lang="en"],
.c-fares__aside p [lang="en"],
.c-appblock__qrtext [lang="en"] {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  line-height: var(--lh-en-body);
}

/* ── External-link mark ───────────────────────────────────────────────────── */
.c-ext { width: 0.85em; height: 0.85em; flex: 0 0 auto; opacity: 0.75; }

/* Every inline SVG in the page paints with currentColor, so icons re-tint per
   theme and per band with no extra rules. No icon font anywhere.

   base.css declares `svg { fill: currentColor }` for solid glyph icons. A CSS
   declaration beats an SVG PRESENTATION ATTRIBUTE, so that rule silently filled
   every STROKED line icon on this page — <svg fill="none" stroke="currentColor">
   rendered as a solid red blob. Icons drawn with a stroke announce it in the
   markup, so keying off that attribute restores them without redefining base.css
   and without touching the genuinely solid icons (Facebook, X, YouTube, Apple,
   the QR block), whose own children carry fill="currentColor". */
svg[stroke="currentColor"] { fill: none; }
svg[aria-hidden="true"] { pointer-events: none; }


/* ══ 2 · .c-utilitybar ════════════════════════════════════════════════════ */

.c-utilitybar {
  background: var(--surface-invert);
  border-bottom: var(--rule-w-strong) solid var(--highlight);
  font-size: var(--fs-small);
}
.c-utilitybar .u-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-4);
  padding-block: 0;
}
.c-utilitybar__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
}
.c-utilitybar__label {
  flex: 0 0 auto;
  margin-inline-end: var(--sp-2);
  color: var(--ink-2);
}
/* 1.15, not --lh-en-body: this two-line micro label sets the height of the whole
   tool row, and 1.6 pushed the row from 44px to 49px. */
.c-utilitybar__label [lang="en"] { font-size: var(--fs-micro); line-height: 1.15; }

/* Language switch — labels in their own script, never flags. */
.c-utilitybar__langswitch { display: flex; align-items: center; gap: var(--sp-1); }
.c-utilitybar__langswitch a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  min-width: var(--tap);
  padding-inline: var(--sp-3);
  border: var(--rule-w) solid transparent;
  border-radius: var(--radius);
  color: var(--ink);
  font-size: var(--fs-small);
  text-decoration: none;
}
.c-utilitybar__langswitch a:hover { text-decoration: underline; }
.c-utilitybar__langswitch a[aria-current] {
  background: var(--highlight);
  border-color: var(--highlight);
  color: var(--surface-invert);
  font-weight: 700;
}

/* Tools — text-size stepper, contrast toggle, theme switcher. */
.c-utilitybar__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
}
/* The A- / A / A+ stepper is one segmented control: collapsing the gap and the
   shared border reads as a single instrument and saves 24px of a 358px row. */
.c-utilitybar__group[role="group"] { gap: 0; }
.c-utilitybar__group[role="group"] > button + button {
  margin-inline-start: calc(-1 * var(--rule-w));
}
.c-utilitybar__tools button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  min-height: var(--tap);
  min-width: var(--tap);
  padding-inline: var(--sp-2);
  background: color-mix(in srgb, var(--ink-invert) 10%, transparent);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: var(--font-en);
  font-size: var(--fs-small);
  font-weight: 700;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease);
}
.c-utilitybar__tools button:hover {
  background: color-mix(in srgb, var(--ink-invert) 22%, transparent);
}
.c-utilitybar__tools button[aria-pressed="true"] {
  background: var(--highlight);
  border-color: var(--highlight);
  color: var(--surface-invert);
}
/* The text-size control is a STEPPER, so its honest state is "can I still go
   further", which is aria-disabled — theme-switcher.js sets it at each end of
   the ladder. It stays focusable and keeps its 44px target; only the affordance
   dims, and it is never the sole signal (the page size itself changes). */
.c-utilitybar__tools button[aria-disabled="true"] {
  opacity: 0.55;
  border-style: dashed;
}
.c-utilitybar__tools button > svg { width: 1.15em; height: 1.15em; }

/* Theme switcher. A real <select> with a real <label for> — it keeps working
   with the keyboard, with a screen reader and with JS switched off (in which
   case the server-rendered default theme simply stands). */
.c-utilitybar__select {
  min-height: var(--tap);
  max-width: 100%;
  padding: var(--sp-1) var(--sp-2);
  background: var(--surface-3);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-small);
}
/* The native popup paints with the control's own colours, so the control and its
   options are given an OPAQUE dark plate (a color-mix against --surface-invert,
   not against transparent) — otherwise the dropdown can render dark-on-dark.
   Measured: --ink-invert on this plate is 10.8:1 in livery. */
.c-utilitybar__select,
.c-utilitybar__select option {
  background: color-mix(in srgb, var(--ink-invert) 12%, var(--surface-invert));
  color: var(--ink-invert);
}

.c-utilitybar__tollfree {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding-inline: var(--sp-2);
  border-radius: var(--radius);
  color: var(--ink);
  font-size: var(--fs-small);
  text-decoration: none;
}
.c-utilitybar__tollfree > svg { width: 1.25em; height: 1.25em; flex: 0 0 auto; }
.c-utilitybar__tollfree b {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  color: var(--highlight);
}
.c-utilitybar__tollfree:hover b { text-decoration: underline; }


/* ══ 3 · .c-masthead / .c-nav ═════════════════════════════════════════════ */

.c-masthead {
  position: relative;
  z-index: 3;
  background: var(--surface-3);
  border-bottom: var(--rule-w-strong) solid var(--rule-strong);
}
.c-masthead .u-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-5);
  padding-block: var(--sp-2);
}
/* Never a bare <img>: the lockup is always inside its own link. */
.c-masthead__logo {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: var(--sp-1);
  border-radius: var(--radius);
  text-decoration: none;
}
.c-masthead__logo img {
  display: block;
  width: auto;
  height: clamp(2.75rem, 1.6rem + 3.4vw, 3.8rem);   /* never below the 40px floor */
  max-width: 100%;
}

.c-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--sp-1) var(--sp-2);
}
.c-nav__link {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1em;
  min-height: var(--tap);
  min-width: var(--tap);
  padding: var(--sp-1);
  border-bottom: var(--rule-w-strong) solid transparent;
  border-radius: var(--radius) var(--radius) 0 0;
  color: var(--ink);
  font-size: var(--fs-small);
  font-weight: 650;
  line-height: var(--lh-display);
  text-decoration: none;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.c-nav__link [lang="ml"] { font-size: var(--fs-small); }
/* Sentence case, not uppercase: tracked uppercase made each nav link about a
   quarter wider, which cost an entire extra wrapped row at 390px. */
.c-nav__link [lang="en"] {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--ink-2);
}
.c-nav__link:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-bottom-color: var(--accent);
}
.c-nav__link[aria-current] {
  border-bottom-color: var(--accent);
  color: var(--accent-strong);
}
.c-nav__link[aria-current] [lang="en"] { color: var(--accent-text); }

/* .c-nav carries EXACTLY the five passenger-task items the contract names — no
   sixth "Book Ticket" plate. On a 390px phone that sixth item cost a whole
   wrapped nav row, and the booking deep link (Annexure II #1) is already carried
   prominently by the hero's gold CTA immediately below the masthead, by
   .c-search__book, by a quick-task tile and by the footer. */


/* ══ 4 · .c-hero — the centrepiece ════════════════════════════════════════ */

/* THE OVERLAP, declared once for both of the components that have to agree about
   it: .c-hero reserves exactly this much slack below its content, and .c-search
   rides up by exactly this much. Getting it wrong is not cosmetic — at 56px of
   overlap with only 16px of slack the card cut the hero's primary CTA in half on
   a desktop viewport. */
.c-hero,
.c-search-band { --hero-overlap: clamp(1.5rem, 3vw, 2.5rem); }

.c-hero {
  /* ONE number governs the whole composition: how far down the copy starts. The
     photograph gets that band clear, and the scrim's opaque zone is anchored to
     exactly the same length — so the <h1> can never drift out of the protected
     area as the viewport or the text size changes. That coupling is the reason
     the measured contrast below holds at 390px and at 1440px. */
  --hero-pad-top: clamp(2.5rem, -1rem + 12vw, 9rem);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(21rem, 10vw + 18rem, 34rem);
  background: var(--surface-invert);
  color: var(--ink-invert);
  border-bottom: var(--rule-w-strong) solid var(--highlight);
}

/* The one eager raster on the page. Absolutely positioned so the copy below can
   set the hero's height from its own content — no aspect-ratio box to fight,
   and no CLS because width/height are on the <img>. */
.c-hero__media { position: absolute; inset: 0; z-index: 0; display: block; }
.c-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* favour the red Super Fast Premium half when the crop gets narrow */
  object-position: 68% 48%;
}

/* ── .c-hero__scrim — LOAD-BEARING, not decoration ────────────────────────
   Audit finding P2 is white display type over a busy bus photograph at
   uncontrolled contrast. This is the fix: a gradient that makes the lower
   two-thirds of the hero effectively solid --surface-invert, so the <h1> never
   sits on raw photograph. The top of the frame stays open so the buses are
   still the picture.

   MEASURED, not asserted. The number below is the WORST pixel found anywhere
   inside the <h1>'s own box: the page was rendered at 390x844 and at 1440x900
   in all four themes, the <h1> was made invisible, its box was screenshotted,
   every pixel's WCAG relative luminance was computed, and the LIGHTEST pixel
   (the worst case for light type) was taken as the backdrop.

     viewport   livery    thaneer   yathra    ticket
     390x844    13.85:1   14.79:1   14.12:1   14.32:1
     1440x900   13.85:1   14.79:1   14.12:1   14.32:1

   Required floor: 4.5:1 for body text, 3:1 for >=24px bold. The worst of the
   eight measurements is 13.85:1 — 3.1x the strictest requirement. It is
   identical at both viewports because the opaque zone is anchored to
   --hero-pad-top, a length, rather than to a percentage of a height that
   changes.

   The gradient reaches >=97% at exactly --hero-pad-top and 99% below that, so
   the photograph contributes at most 3% of the backdrop under the copy; the
   left-to-right layer stacks further opacity on the side the copy sits on. The
   top of the frame is left almost clear, which is where the buses actually are.
   "It looks fine" is not a measurement, and audit P2 is what happens without
   one. */
.c-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--surface-invert) 8%, transparent) 0,
      color-mix(in srgb, var(--surface-invert) 30%, transparent) calc(var(--hero-pad-top) * 0.5),
      color-mix(in srgb, var(--surface-invert) 86%, transparent) calc(var(--hero-pad-top) * 0.86),
      color-mix(in srgb, var(--surface-invert) 97%, transparent) var(--hero-pad-top),
      color-mix(in srgb, var(--surface-invert) 99%, transparent) 100%),
    linear-gradient(to right,
      color-mix(in srgb, var(--surface-invert) 58%, transparent) 0%,
      color-mix(in srgb, var(--surface-invert) 22%, transparent) 62%,
      color-mix(in srgb, var(--surface-invert) 4%, transparent) 100%);
}

/* On a wide viewport the copy only needs about half the measure, so the
   statistics sit BESIDE it rather than under it — which takes roughly 200px off
   the hero's height and puts the journey search back inside a 900px-tall fold.
   On a phone both bases collapse to 100% and they stack, with no media query. */
.c-hero .u-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 var(--sp-6);
}
.c-hero__copy {
  flex: 1 1 min(100%, 26rem);
  min-width: 0;
  position: relative;
  z-index: 2;
  /* the photo breathes above the copy; the same length feeds the scrim */
  padding-top: var(--hero-pad-top);
  padding-bottom: calc(var(--hero-overlap) + var(--sp-2));
}
/* --lh-body, not --lh-display: this is a <p>, so wrapped Malayalam inside it
   must clear the 1.7 line-height floor. */
.c-hero__eyebrow {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-2);
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-small);
  font-weight: 650;
  line-height: var(--lh-body);
  color: var(--highlight);
}
.c-hero__eyebrow b { font-family: var(--font-en); font-variant-numeric: tabular-nums; }
.c-hero__copy h1 {
  margin: 0;
  max-width: 26ch;
  font-size: var(--fs-h1);
  line-height: var(--lh-display);
  color: var(--ink-invert);
  text-wrap: balance;
}
.c-hero__copy h1 [lang="ml"] { display: block; font-weight: 800; }
.c-hero__copy h1 [lang="en"] {
  display: block;
  margin-top: 0.15em;
  font-size: clamp(0.95rem, 0.8rem + 0.6vw, 1.25rem);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--highlight);
}
.c-hero__rule {
  width: clamp(4rem, 12vw, 8rem);
  height: var(--rule-w-strong);
  margin: var(--sp-2) 0;
  background: var(--highlight);
  border: 0;
}
.c-hero__standfirst {
  margin: 0 0 var(--sp-4);
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-hero__standfirst [lang="en"] { display: block; }
/* ONE primary action in the hero. A second, weaker CTA here cost a whole
   wrapped row on a 390px phone and pushed the journey search further down the
   page — and the search card immediately below already carries both "find buses"
   and "book online". */
.c-hero__cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.c-hero__cta > a { flex: 0 1 auto; }

/* Verified statistics, set like the data plate on the side of a bus. */
.c-hero__stats {
  position: relative;
  z-index: 2;
  flex: 1 1 min(100%, 20rem);
  max-width: 26rem;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 5.5rem), 1fr));
  gap: var(--sp-3) 0;
  margin: 0;
  /* the same slack the copy column reserves, so whichever column is the taller
     one, the card lands on padding and never on content */
  padding: var(--sp-3) 0 calc(var(--hero-overlap) + var(--sp-2));
  --rule: color-mix(in srgb, var(--ink-invert) 30%, transparent);
}


/* ══ 5 · .c-search — the primary task ═════════════════════════════════════ */

.c-search-band {
  position: relative;
  z-index: 2;
  background: var(--surface);
  padding-block: 0 var(--band-y);
}
.c-search {
  position: relative;
  /* The one intentional overlap in the page: the card rides up over the hero's
     lower edge, so the primary task is reachable without scrolling on a phone
     and the seam reads as one composition rather than two stacked bands. */
  margin-top: calc(-1 * var(--hero-overlap));
  padding: clamp(var(--sp-4), 2vw, var(--sp-6));
  background: var(--surface-3);
  border: var(--rule-w) solid var(--rule);
  border-top: var(--rule-w-strong) solid var(--rule-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.c-search__head { margin-bottom: var(--sp-4); }
.c-search__head h2 {
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  margin: 0;
  font-size: var(--fs-h2);
  line-height: var(--lh-display);
  color: var(--accent-strong);
}
.c-search__head h2 [lang="ml"] { font-weight: 800; }
.c-search__head h2 [lang="en"] {
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-search__hint {
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-search__hint [lang="en"] { display: block; line-height: var(--lh-en-body); }

.c-search__fields {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--sp-3);
}
.c-search__field {
  flex: 1 1 min(100%, 12rem);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
}
/* A placeholder is not a label. Every control here has a real <label for>. */
.c-search__field label {
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-display);
  color: var(--ink);
}
.c-search__field label [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-search__field input {
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface);
  border: var(--rule-w-strong) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-body);
}
.c-search__field input::placeholder { color: var(--ink-2); opacity: 1; }
.c-search__field input:hover { border-color: var(--accent-text); }
/* The <select> this field also wraps is styled in the §15 addendum at the foot of
   this file — added there by the depot-directory page for the same reason the
   fare calculator needed it. One rule, not two. */

.c-search__swap {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  margin-bottom: 0.1rem;
  background: var(--surface);
  border: var(--rule-w-strong) solid var(--rule);
  border-radius: var(--radius);
  color: var(--accent-text);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.c-search__swap > svg { width: 1.5rem; height: 1.5rem; }
.c-search__swap:hover { background: var(--accent); color: var(--ink-on-accent); }

.c-search__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.c-search__submit { flex: 1 1 min(100%, 16rem); font-size: var(--fs-body); }
.c-search__book { flex: 1 1 min(100%, 16rem); }
.c-search__book [lang="en"] {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
}
.c-search__note {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 0;
  padding-top: var(--sp-3);
  border-top: var(--rule-w) solid var(--rule);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-search__note [lang="en"] { line-height: var(--lh-en-body); }
.c-search__note a { color: var(--accent-text); }


/* ══ 6 · .c-band / .c-sechead / section dividers ══════════════════════════ */

.c-band {
  --band-bg: var(--surface);
  position: relative;
  padding-block: var(--band-y);
  background: var(--band-bg);
}
.c-band--cream  { --band-bg: var(--surface-2); }
.c-band--alt    { --band-bg: var(--surface-3); }
.c-band--accent { --band-bg: var(--surface-accent); }
.c-band--invert { --band-bg: var(--surface-invert); }

.c-sechead {
  max-width: var(--measure);
  margin-bottom: clamp(var(--sp-5), 3vw, var(--sp-6));
}
.c-sechead h2 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-3);
  margin: 0;
  font-size: var(--fs-h2);
  line-height: var(--lh-display);
  color: var(--accent-strong);
}
.c-sechead h2 [lang="ml"] { font-weight: 800; }
.c-sechead h2 [lang="en"] {
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-sechead__rule {
  width: clamp(3rem, 8vw, 5.5rem);
  height: var(--rule-w-strong);
  margin: var(--sp-3) 0 0;
  background: var(--accent);
  border: 0;
}
.c-sechead p {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-sechead p [lang="en"] { display: block; }

/* ── Section divider, keyed off --divider ─────────────────────────────────
   --divider is an identifier, not a colour or a length, so it is consumed with
   a CSS style query: @container style(--divider: wave). The element is the
   INCOMING band's own colour, positioned just above its top edge, so the new
   band appears to sweep / curve / notch into the previous one. --band-bg means
   it needs no knowledge of which variant it is in.

   Everything here is pure CSS geometry — clip-path, border-radius, gradients
   and a mask. No raster, no inline SVG, no extra HTTP request. If style queries
   are unsupported the base rule below still draws a clean hairline seam, so the
   motif is an enhancement and never load-bearing. */
.c-band__divider {
  --divider-h: clamp(1.5rem, 3.2vw, 3.25rem);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--divider-h);
  pointer-events: none;
}
.c-band__divider::before,
.c-band__divider::after { content: ""; position: absolute; }

/* fallback seam, used if style queries are unsupported: a hairline in the
   structural rule colour, sitting exactly on the join */
.c-band__divider {
  background-image: linear-gradient(to top,
    var(--rule-strong) 0 var(--rule-w), transparent var(--rule-w));
}

/* LIVERY — the angled livery sweep, with the gold pinstripe that runs along the
   flank of a Super Fast Premium. */
@container style(--divider: livery-sweep) {
  .c-band__divider {
    background-image: none;
    background-color: var(--band-bg);
    clip-path: polygon(0 100%, 100% 0, 100% 100%);
  }
  .c-band__divider::before {
    inset: 0;
    background: var(--highlight);
    clip-path: polygon(0 100%, 100% 0, 100% -0.4rem, 0 calc(100% - 0.4rem));
  }
}

/* THANEER — a soft backwater curve. Two quarter-ellipses meeting in the middle;
   curves, so border-radius rather than clip-path. */
@container style(--divider: wave) {
  .c-band__divider { background-image: none; background-color: transparent; }
  .c-band__divider::before,
  .c-band__divider::after {
    top: 0;
    bottom: 0;
    width: 50.4%;
    background: var(--band-bg);
  }
  .c-band__divider::before { left: 0;  border-top-right-radius: 100% 100%; }
  .c-band__divider::after  { right: 0; border-top-left-radius: 100% 100%; }
}

/* YATHRA — a dotted route line with transit stop rings on the seam. */
@container style(--divider: route-line) {
  .c-band__divider {
    --divider-h: clamp(1.25rem, 2.4vw, 2rem);
    background-image: none;
    background-color: transparent;
  }
  .c-band__divider::before {
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--rule-w-strong);
    background-image: repeating-linear-gradient(to right,
      var(--rule-strong) 0 0.5rem, transparent 0.5rem 1.125rem);
  }
  .c-band__divider::after {
    left: 0;
    right: 0;
    bottom: -0.3125rem;
    height: 0.625rem;
    background-image: radial-gradient(circle at 50% 50%,
      var(--band-bg) 0 0.125rem,
      var(--rule-strong) 0.125rem 0.21rem,
      transparent 0.21rem);
    background-size: 25% 100%;
    background-repeat: repeat-x;
  }
}

/* TICKET — a perforated notch edge. The band's own colour is masked with a row
   of half-circles, so the previous band shows through the punch-outs. The mask
   uses currentColor purely for its alpha; no colour literal is involved. */
@container style(--divider: perforation) {
  .c-band__divider {
    --divider-h: clamp(0.75rem, 1.6vw, 1.125rem);
    --notch: clamp(0.5rem, 1.1vw, 0.75rem);
    background-image: none;
    background-color: var(--band-bg);
    -webkit-mask-image: radial-gradient(circle at 50% 0,
      transparent calc(var(--notch) - 1px), currentColor var(--notch));
    mask-image: radial-gradient(circle at 50% 0,
      transparent calc(var(--notch) - 1px), currentColor var(--notch));
    -webkit-mask-size: calc(var(--notch) * 2) 100%;
    mask-size: calc(var(--notch) * 2) 100%;
    -webkit-mask-repeat: repeat-x;
    mask-repeat: repeat-x;
    -webkit-mask-position: center top;
    mask-position: center top;
  }
  .c-band__divider::before,
  .c-band__divider::after { content: none; }
}


/* ══ 7 · .c-tasks ═════════════════════════════════════════════════════════ */

/* 170px basis: two columns at 390px, six at 1440px, with no media query.
   Widening the viewport re-flows continuously rather than snapping. */
.c-tasks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: var(--sp-3);
}
.c-tasks__item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: calc(var(--tap) * 2);
  padding: var(--sp-4) var(--sp-3);
  background: var(--surface-3);
  /* the rule, not the shadow, is what separates this card — livery and yathra
     have --shadow: none */
  border: var(--rule-w) solid var(--rule);
  border-left: var(--rule-w-strong) solid var(--accent);
  border-radius: var(--radius);
  color: var(--ink);
  font-size: var(--fs-small);
  font-weight: 650;
  line-height: var(--lh-display);
  text-decoration: none;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.c-tasks__item > svg {
  width: clamp(1.75rem, 3vw, 2.25rem);
  height: clamp(1.75rem, 3vw, 2.25rem);
  flex: 0 0 auto;
  color: var(--accent-text);
}
.c-tasks__item [lang="ml"] { display: block; font-size: var(--fs-small); }
.c-tasks__item [lang="en"] {
  display: block;
  margin-top: 0.15em;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-2);
}
/* 14%, not more: on the red band a heavier gold wash lifts the plate to 4.57:1
   for --ink-on-accent. At 14% it measures 5.18:1. */
.c-tasks__item:hover {
  background: color-mix(in srgb, var(--highlight) 14%, var(--surface-3));
  border-left-color: var(--accent-strong);
  transform: translateY(-2px);
}


/* ══ 8 · .c-notices / .c-notice ═══════════════════════════════════════════ */

.c-notices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(15rem, 24vw, 23rem)), 1fr));
  gap: var(--sp-4);
}
/* The band-level "this copy is illustrative" bar. No tracking and no micro size
   on the container: the only element carrying those is the [lang="en"] badge
   inside it, so Malayalam can never inherit either. */
.c-notices__samplebar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3);
  background: color-mix(in srgb, var(--highlight) 20%, transparent);
  border: var(--rule-w) solid var(--accent-text);
  border-left: var(--rule-w-strong) solid var(--accent-text);
  border-radius: var(--radius);
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: var(--lh-body);
  color: var(--ink);
}
.c-notices__samplebar [lang="en"]:not(.c-notice__sample) {
  font-weight: 500;
  line-height: var(--lh-en-body);
  color: var(--ink-2);
}

.c-notice {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--surface-3);
  border: var(--rule-w) solid var(--rule);
  border-top: var(--rule-w-strong) solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.c-notice__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin: 0;
}
.c-notice__chip { color: var(--accent-strong); }
.c-notice__chip--city { color: var(--ink); }
.c-notice__chip--city > svg { color: var(--accent-text); }
.c-notice__date {
  font-family: var(--font-en);
  font-size: var(--fs-micro);        /* Western Arabic numerals only, no script */
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.c-notice h3 {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-display);
  color: var(--ink);
}
.c-notice h3 [lang="ml"] { display: block; font-weight: 750; }
.c-notice h3 [lang="en"] {
  display: block;
  margin-top: 0.2em;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink-2);
}
.c-notice p {
  margin: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-notice p[lang="en"] { line-height: var(--lh-en-body); }
.c-notice__more { margin-top: auto; }
.c-notice__more a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: var(--tap);
  color: var(--accent-text);
  font-size: var(--fs-small);
  font-weight: 650;
}
/* this one lives inside a <p>, so its stacked Malayalam keeps the 1.7 floor */
.c-notices__more { margin: var(--sp-5) 0 0; }
.c-notices__more > a { line-height: var(--lh-body); }


/* ══ 9 · .c-fares ═════════════════════════════════════════════════════════ */

.c-fares__layout { display: flex; flex-wrap: wrap; gap: var(--sp-5); }
.c-fares__main { flex: 3 1 min(100%, 26rem); min-width: 0; }
.c-fares__aside {
  flex: 2 1 min(100%, 17rem);
  min-width: 0;
  align-self: start;
  padding: var(--sp-4);
  background: var(--surface-invert);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* an inverted panel: re-point the ink tokens once, children follow */
  --ink: var(--ink-invert);
  --ink-2: color-mix(in srgb, var(--ink-invert) 78%, transparent);
  --rule: color-mix(in srgb, var(--ink-invert) 26%, transparent);
  /* --highlight is a FILL/RULE colour, not a text colour. Using it here measured
     4.33:1 at 15px in the yathra theme, whose --highlight is orange rather than gold.
     --accent-on-invert is the text-safe accent for inverted surfaces. */
  --accent-text: var(--accent-on-invert);
  --accent-strong: var(--accent-on-invert);
  color: var(--ink);
}
.c-fares__aside h3 {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-h3);
  line-height: var(--lh-display);
  color: var(--accent-strong);
}
.c-fares__aside h3 [lang="en"] {
  display: block;
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-fares__aside p {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-fares__aside p:last-child { margin-bottom: 0; }
.c-fares__aside p [lang="en"] { display: block; line-height: var(--lh-en-body); }
.c-fares__eq {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3);
  background: color-mix(in srgb, var(--ink-invert) 10%, transparent);
  border-left: var(--rule-w-strong) solid var(--highlight);
  border-radius: var(--radius);
  font-size: var(--fs-small);
  font-weight: 650;
  color: var(--ink);
}

/* A wide table stays scrollable inside its own region rather than pushing the
   viewport sideways. role="region" + tabindex="0" so it is keyboard-reachable
   and announced, per WCAG 1.4.10 / 2.1.1. */
.c-fares__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface-3);
}
.c-fares {
  width: 100%;
  min-width: 22rem;
  border-collapse: collapse;
  font-size: var(--fs-small);
}
.c-fares caption {
  padding: var(--sp-3);
  border-bottom: var(--rule-w) solid var(--rule);
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-body);
  text-align: start;
  color: var(--ink);
}
.c-fares caption [lang="en"] {
  display: block;
  font-weight: 500;
  line-height: var(--lh-en-body);
  color: var(--ink-2);
}
.c-fares th,
.c-fares td {
  padding: var(--sp-3);
  border-bottom: var(--rule-w) solid var(--rule);
  line-height: var(--lh-body);
  text-align: start;
  vertical-align: baseline;
}
.c-fares thead th {
  background: var(--surface-2);
  border-bottom: var(--rule-w-strong) solid var(--rule-strong);
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--ink);
}
.c-fares thead th [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-fares tbody th {
  font-weight: 700;
  color: var(--ink);
}
.c-fares tbody th [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  color: var(--ink-2);
}
/* header cells align with the numeric columns but keep the document's own font:
   .c-fares__num is Latin-only and never lands on a cell holding Malayalam */
.c-fares thead th:nth-child(n + 2) { text-align: end; }
.c-fares tbody tr:nth-child(even) th,
.c-fares tbody tr:nth-child(even) td { background: var(--surface-2); }
.c-fares tbody tr:last-child th,
.c-fares tbody tr:last-child td { border-bottom: 0; }
.c-fares__num {
  font-family: var(--font-en);
  font-size: var(--fs-body);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  text-align: end;
  white-space: nowrap;
  color: var(--ink);
}
.c-fares__note {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-fares__note [lang="en"] { display: block; line-height: var(--lh-en-body); }


/* ══ 10 · .c-dest ═════════════════════════════════════════════════════════ */

/* Two columns at 390px, three from roughly 700px up. The clamp() inside the
   minmax() is what makes that fluid instead of a breakpoint. */
.c-dest {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(10rem, 24vw, 22rem)), 1fr));
  gap: var(--sp-4);
}
.c-dest__card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface-3);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  text-decoration: none;
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.c-dest__figure {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
}
.c-dest__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform calc(var(--dur) * 1.5) var(--ease);
}
.c-dest__cap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  border-top: var(--rule-w-strong) solid var(--accent);
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-display);
}
.c-dest__cap [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-dest__go {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  flex: 0 0 auto;
  /* --accent-text is certified against --surface, but this label sits on the destination
     card's scrim, which is a different ground: measured 4.33:1 in the yathra theme, under
     the 4.5 floor. --accent-strong is the darker derivative and clears it on every theme's
     card ground. Do not "simplify" this back to --accent-text. */
  color: var(--accent-strong);
  font-size: var(--fs-small);        /* holds Malayalam — never --fs-micro */
  font-weight: 700;
}
.c-dest__go [lang="en"] { font-size: var(--fs-micro); font-weight: 500; }
.c-dest__go > svg { width: 1.1rem; height: 1.1rem; flex: 0 0 auto; }
.c-dest__card:hover { transform: translateY(-3px); border-color: var(--accent); }
.c-dest__card:hover .c-dest__figure img { transform: scale(1.04); }


/* ══ 11 · .c-stat ═════════════════════════════════════════════════════════ */

.c-stat {
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  min-width: 0;
  padding-left: var(--sp-3);
  border-left: var(--rule-w-strong) solid var(--highlight);
}
.c-stat dt {
  order: 2;
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: var(--lh-display);
  color: var(--ink-2);
}
.c-stat dt [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
}
.c-stat dd {
  order: 1;
  margin: 0;
  font-family: var(--font-en);
  font-size: clamp(1.35rem, 1rem + 1.4vw, 2rem);
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  line-height: 1.15;
  color: var(--ink);
}


/* ══ 12 · .c-footer / .c-appblock / .c-social / .c-staff / .c-legal ═══════ */

.c-footer {
  position: relative;
  background: var(--surface-invert);
  --band-bg: var(--surface-invert);
  border-top: var(--rule-w-strong) solid var(--highlight);
}
.c-footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(10rem, 15vw, 13.5rem)), 1fr));
  gap: var(--sp-5) var(--sp-4);
  padding-block: var(--band-y) var(--sp-6);
}
.c-footer__col > h2 {
  margin: 0 0 var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: var(--rule-w) solid var(--rule);
  font-size: var(--fs-body);
  line-height: var(--lh-display);
  color: var(--accent-text);
}
.c-footer__col > h2 [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-footer__col ul { margin: 0; padding: 0; list-style: none; }
.c-footer__col li { margin: 0; }
.c-footer__col li > a {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-1) 0;
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  text-decoration: none;
}
.c-footer__col li > a:hover { color: var(--accent-text); text-decoration: underline; }
.c-footer__tel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1em;
  min-height: var(--tap);
  padding: var(--sp-1) 0;
  color: var(--ink);
  text-decoration: none;
}
.c-footer__tel span {
  font-size: var(--fs-small);
  line-height: var(--lh-display);
  color: var(--ink-2);
}
.c-footer__tel b {
  font-family: var(--font-en);
  font-size: var(--fs-body);
  font-variant-numeric: tabular-nums;
  color: var(--accent-text);
  overflow-wrap: anywhere;
}
.c-footer__tel:hover b { text-decoration: underline; }
.c-footer__addr {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}

/* ── .c-appblock — Annexure II #6: badges AND a QR, in the footer and in the
   page body. Badges are inline SVG built in-house: hotlinking the real Play /
   App Store artwork would add a third-party origin, which the budget forbids
   and the audit already flags. The store URLs are placeholders in Annexure II,
   so they are href="#" here rather than invented. */
.c-appblock { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: stretch; }
.c-appblock__badges {
  display: flex;
  flex-wrap: wrap;
  flex: 1 1 min(100%, 11rem);
  gap: var(--sp-2);
  align-content: start;
}
/* --surface-3, not an --ink wash: on the red band a 10% light wash measured
   4.34:1 for --ink-on-accent, below AA. --surface-3 is re-pointed per band
   (lightened on dark bands, darkened on the accent band) and measures 12.2:1
   and 6.28:1 respectively. */
.c-appblock__badge {
  flex: 1 1 min(100%, 10rem);
  justify-content: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-3);
  border-color: var(--rule);
  border-width: var(--rule-w);
  color: var(--ink);
  font-size: var(--fs-small);
  font-weight: 650;
  text-align: start;
}
.c-appblock__badge [lang="en"] {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.03em;
  color: var(--ink-2);
}
.c-appblock__badge:hover { background: color-mix(in srgb, var(--ink) 14%, var(--surface-3)); }
/* the app block's own small heading — subordinate, but not the Staff Corner's */
.c-appblock__h {
  margin: var(--sp-6) 0 var(--sp-3);
  font-size: var(--fs-body);
  line-height: var(--lh-display);
  color: var(--accent-text);
}
.c-appblock__h [lang="en"] {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
/* Shrinkable: in a ~216px footer column the badge text plus the QR block was
   223px wide and spilled past the column edge. flex-basis min(100%, …) plus
   min-width:0 lets it compress instead of overflowing. */
.c-appblock__qr {
  flex: 1 1 min(100%, 11rem);
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--surface-3);
  border: var(--rule-w) dashed var(--rule);
  border-radius: var(--radius);
}
.c-appblock__qr svg {
  width: clamp(3.5rem, 8vw, 4.5rem);
  height: clamp(3.5rem, 8vw, 4.5rem);
  flex: 0 0 auto;
  color: var(--ink);
}
.c-appblock__qrtext {
  min-width: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-appblock__qrtext .c-appblock__sample { margin-bottom: var(--sp-1); white-space: normal; }

/* ── .c-social — Annexure II #7. Inline SVG, accessible names, 44px targets.
   The handles are placeholders in the annexure, so href="#" and nothing
   invented. */
.c-social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 0;
  padding: 0;
  list-style: none;
}
.c-social li { margin: 0; }
.c-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  background: color-mix(in srgb, var(--ink-invert) 10%, transparent);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.c-social a > svg { width: 1.35rem; height: 1.35rem; }
.c-social a:hover { background: var(--highlight); color: var(--surface-invert); }

/* ── .c-staff — Annexure II #4. Deliberately SUBORDINATE: recessed surface,
   smaller heading, muted ink, last thing before the legal row. The audit found
   staff logins outranking journey planning on the live home page; this is where
   they belong. Never a peer of citizen content. */
.c-staff {
  background: color-mix(in srgb, var(--ink-invert) 6%, transparent);
  border-top: var(--rule-w) solid var(--rule);
}
.c-staff .u-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-5);
  padding-block: var(--sp-3);
}
.c-staff__h {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-display);
  color: var(--ink-2);
}
.c-staff__h [lang="en"] {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.c-staff__note {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-staff__note > svg { width: 1.1em; height: 1.1em; flex: 0 0 auto; }
.c-staff ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.c-staff li { margin: 0; }
.c-staff li > a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: var(--tap);
  min-width: var(--tap);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.c-staff li > a:hover { color: var(--ink); }

/* ── .c-legal ─────────────────────────────────────────────────────────────── */
.c-legal { border-top: var(--rule-w) solid var(--rule); }
.c-legal .u-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-4);
  padding-block: var(--sp-3);
}
.c-legal ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.c-legal li { margin: 0; }
.c-legal li > a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  min-width: var(--tap);
  color: var(--ink-2);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  text-decoration: none;
}
.c-legal li > a:hover { color: var(--accent-text); text-decoration: underline; }
.c-legal__copy {
  margin: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}


/* ══ 13 · OPTIONAL MODULES ════════════════════════════════════════════════
   Structural signatures that a token cannot express, so they ship as modules
   any theme may opt into rather than as themes. A theme switch never changes
   the DOM; opting into a module does. */

/* .u-perforate — the ticket tear-edge. Half-circle punch-outs along the top and
   bottom edge of whatever it is applied to, cut with a mask so the surface
   behind shows through. currentColor is used only for the mask's alpha. */
.u-perforate {
  --notch: 0.625rem;
  -webkit-mask-image:
    radial-gradient(circle at 50% 0, transparent calc(var(--notch) - 1px), currentColor var(--notch)),
    radial-gradient(circle at 50% 100%, transparent calc(var(--notch) - 1px), currentColor var(--notch));
  mask-image:
    radial-gradient(circle at 50% 0, transparent calc(var(--notch) - 1px), currentColor var(--notch)),
    radial-gradient(circle at 50% 100%, transparent calc(var(--notch) - 1px), currentColor var(--notch));
  -webkit-mask-size: calc(var(--notch) * 2) 50%, calc(var(--notch) * 2) 50%;
  mask-size: calc(var(--notch) * 2) 50%, calc(var(--notch) * 2) 50%;
  -webkit-mask-position: left top, left bottom;
  mask-position: left top, left bottom;
  -webkit-mask-repeat: repeat-x, repeat-x;
  mask-repeat: repeat-x, repeat-x;
}

/* .network-diagram — an inline-SVG transit/zone diagram. Geometry is authored in
   the markup; every stroke and fill here is a token, so one diagram serves all
   four themes. */
.network-diagram { width: 100%; overflow-x: auto; }
.network-diagram svg { display: block; width: 100%; height: auto; }
.network-diagram .nd-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.network-diagram .nd-line--city { stroke: var(--highlight); }
.network-diagram .nd-stop {
  fill: var(--surface-3);
  stroke: var(--ink);
  stroke-width: 3;
}
.network-diagram .nd-label {
  fill: var(--ink);
  font-family: var(--font-ml);
  font-size: 15px;      /* --fs-small floor: SVG text needs an absolute size */
}
.network-diagram .nd-label--en {
  fill: var(--ink-2);
  font-family: var(--font-en);
  font-size: 13px;      /* Latin only */
}


/* ══ 14 · REDUCED-MOTION BACKSTOP ═════════════════════════════════════════
   tokens.css already sets --dur: 0ms under prefers-reduced-motion, and every
   transition in this file is expressed in var(--dur), so durations collapse on
   their own. This block exists so that the *transforms* themselves — the hover
   lifts and the destination image zoom — are neutralised too, rather than
   snapping instantly to a moved position. Nothing bypasses the token. */
@media (prefers-reduced-motion: reduce) {
  .c-hero__cta > a:hover,
  .c-search__submit:hover,
  .c-search__book:hover,
  .c-appblock__badge:hover,
  .c-notices__more > a:hover,
  .c-tasks__item:hover,
  .c-dest__card:hover,
  .c-dest__card:hover .c-dest__figure img { transform: none; }
}

/* Printing: the interactive furniture is noise on paper. */
@media print {
  .c-utilitybar,
  .c-nav,
  .c-hero__media,
  .c-hero__scrim,
  .c-band__divider,
  .c-social,
  .c-staff { display: none; }
  .c-hero { background: none; color: var(--ink); }
  .c-hero__copy h1,
  .c-hero__standfirst { color: var(--ink); }
}


/* ══ 15 · .c-crumbs · .c-directory ═════════════════════════════════════════
   Added for /ml/sahayam/depot-directory. Both blocks are SYSTEM-level, not
   page-level: the IA calls for a breadcrumb on every one of the ~62 inner pages,
   and for four more directories built from exactly this table — workshops,
   reservation counters, the officer directory and the school-services list.
   Everything below resolves to a semantic token; there is no colour literal, no
   media query and no fixed breakpoint here either.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Breadcrumb. Colour comes from --accent-text, which the band re-points, so
   the same markup reads correctly on cream (7.42:1 in livery) and on an
   inverted band (--accent-text becomes --highlight, gold on near-black). */
.c-crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--sp-2);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-crumbs a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);           /* WCAG 2.5.5 even though it sits in a <p> */
  color: var(--accent-text);
}
.c-crumbs [aria-current] { color: var(--ink); font-weight: 700; }
.c-crumbs__sep { color: var(--ink-2); }

/* ── §5 addendum: the field shell had no styled <select>. .c-search__field
   styled `input` only, so the first page to need an enumerated filter would
   otherwise have shipped a UA-chrome control next to token-styled inputs.
   Declared with exactly the input's values; `appearance` is deliberately NOT
   reset, so the platform keeps drawing its own disclosure arrow. */
.c-search__field select {
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface);
  border: var(--rule-w-strong) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-body);
}
.c-search__field select:hover { border-color: var(--accent-text); }

/* ── A key-figure row for a page that has no photographic hero. .c-stat itself
   is unchanged and does all the typographic work. */
.c-directory__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 7rem), 1fr));
  gap: var(--sp-4) var(--sp-3);
  margin: var(--sp-5) 0 0;
  max-width: 34rem;
}

/* ── The table. NOT .c-fares: that component is a NUMERIC table — it aligns
   every column after the first to the end and paints .c-fares__num in the Latin
   family with tabular figures. A directory is the opposite: its cells are place
   names in Malayalam, so start-aligned headers over start-aligned cells is the
   correct pairing, and a Latin font-family on a cell holding Malayalam would
   drop the conjuncts to a fallback face. */
.c-directory__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background: var(--surface-3);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
}
.c-directory {
  width: 100%;
  min-width: 42rem;                 /* scrolls inside its region below this */
  border-collapse: collapse;
  font-size: var(--fs-small);
}
.c-directory caption {
  padding: var(--sp-3);
  border-bottom: var(--rule-w) solid var(--rule);
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-body);
  text-align: start;
  color: var(--ink);
}
.c-directory caption [lang="en"] {
  display: block;
  font-weight: 500;
  line-height: var(--lh-en-body);
  color: var(--ink-2);
}
.c-directory th,
.c-directory td {
  padding: var(--sp-3);
  border-bottom: var(--rule-w) solid var(--rule);
  line-height: var(--lh-body);
  text-align: start;
  vertical-align: top;
}
.c-directory thead th {
  background: var(--surface-2);
  border-bottom: var(--rule-w-strong) solid var(--rule-strong);
  font-weight: 700;
  white-space: nowrap;
  color: var(--ink);
}
.c-directory thead th [lang="en"] {
  display: block;
  font-size: var(--fs-micro);       /* Latin only — the Malayalam sits above it */
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.c-directory tbody th { font-weight: 750; color: var(--ink); }
.c-directory tbody td { color: var(--ink-2); }
/* No zebra striping on purpose: the filter hides rows, and :nth-child() counts
   hidden ones — the stripes would come out uneven the moment anyone typed. The
   per-row hairline carries the structure instead. */
.c-directory tbody tr:last-child th,
.c-directory tbody tr:last-child td { border-bottom: 0; }
.c-directory tbody tr:hover th,
.c-directory tbody tr:hover td {
  background: color-mix(in srgb, var(--highlight) 12%, transparent);
}

/* A tel: / mailto: inside a cell is an INLINE link, so base.css's
   min-block-size cannot grow it and WCAG 2.5.5 has to be met here. .u-tap is
   also on the element in the markup, so the 44px target survives even if this
   rule is ever lost. */
.c-directory__contact {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sp-2);
  min-height: var(--tap);
  min-width: var(--tap);
  color: var(--accent-text);
  font-family: var(--font-en);      /* only ever wraps a number or an address */
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  /* An address is one token to a reader. Letting it break mid-word rendered
     "adr@ / kerala. / gov.in" over three lines in a 150px column; the table is
     already inside a horizontal scroller, so it may simply be wider instead. */
  white-space: nowrap;
}
.c-directory__hours {
  display: block;
  font-size: var(--fs-small);       /* holds Malayalam — never --fs-micro */
  font-weight: 500;
  line-height: var(--lh-body);
  color: var(--ink-2);
}
/* Each language of the pair stays unbroken and wraps as a WHOLE line. Without
   this the narrow phone column split it as "24 / മണിക്കൂറും · 24 / × 7", which
   detaches a numeral from its unit. */
.c-directory__hours > * { white-space: nowrap; }

/* Result count + the "no match" state. */
.c-directory__status {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-directory__status b { font-variant-numeric: tabular-nums; }

/* Callout: provenance ("15 of 119") and the empty-filter state. The wash is the
   same recipe as .c-notices__samplebar but this is NOT that component — nothing
   on this page is sample content, and it must not carry a sample badge. */
.c-directory__callout {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 0;
  padding: var(--sp-4);
  background: color-mix(in srgb, var(--highlight) 18%, transparent);
  border: var(--rule-w) solid var(--accent-text);
  border-left: var(--rule-w-strong) solid var(--accent-text);
  border-radius: var(--radius);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink);
}
.c-directory__callout [lang="en"] { line-height: var(--lh-en-body); color: var(--ink-2); }
/* `hidden` MUST beat the component's own display. An author `display: flex` on a
   class outranks the UA stylesheet's [hidden] { display: none }, so the
   empty-filter state rendered permanently — a page that says "no depot matches"
   above a full table. Reading el.hidden back reports true and proves nothing;
   this was caught in a screenshot. Every component in this file that sets
   `display` on an element the page toggles needs this pair. */
.c-directory__callout[hidden] { display: none; }


/* ══ 16 · .c-prose · .c-timeline — the LONG-FORM archetype ═════════════════
   Added for /ml/corporation/charithram, and SYSTEM-level rather than page-level:
   the IA carries a dozen more pages of exactly this shape — citizen charter,
   RTI Section 4(1) disclosures, the accessibility statement, booking help,
   cancellation policy, "about us", "future plans".

   WHY IT DID NOT EXIST. Everything above is a page of CARDS. base.css zeroes
   `p` margins deliberately, because on the home page every paragraph belongs to
   a component that sets its own spacing — so running prose had no vertical
   rhythm at all, and nothing capped its line length. That, and a dated spine,
   is the whole of what this section adds: no new colour, no new size, no new
   radius. Every value is an existing token, so all four themes and the
   high-contrast layer carry these two blocks for free.
   ────────────────────────────────────────────────────────────────────────── */

/* ── .c-prose — running prose, capped at --measure (68ch) ──────────────────
   BILINGUAL IDIOM. Long prose does not use .u-bi: a paragraph pair is two <p>
   elements, Malayalam FIRST in the DOM, and the English one is secondary by
   SIZE and WEIGHT — never by a colour that could fail AA. --ink-2 is >= 6.9:1
   on --surface in every theme, 9.5:1 on an inverted band, and full-strength
   --ink-on-accent on the red band, where §1 holds it at full strength on
   purpose. [data-locale="en"] swaps which of the two is dominant in CSS only;
   the DOM never moves, so a screen reader reads Malayalam first in both
   locales, exactly as .u-bi behaves. */
.c-prose { max-inline-size: var(--measure); }
.c-prose > * + * { margin-block-start: var(--sp-4); }
.c-prose p {
  font-size: var(--fs-body);
  line-height: var(--lh-body);       /* 1.75 — the Malayalam floor is 1.7 */
  color: var(--ink);
}
/* The English line sits TIGHT under its Malayalam original: they are one
   paragraph in two scripts, not two paragraphs. */
.c-prose > p[lang="en"] {
  margin-block-start: var(--sp-2);
  font-size: var(--fs-small);
  line-height: var(--lh-en-body);
  color: var(--ink-2);
}
/* Opening paragraph. --lh-body, not --lh-display: this is a <p>, so wrapped
   Malayalam inside it must clear the 1.7 line-height floor. */
.c-prose__lede {
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: var(--lh-body);
}
[data-locale="en"] .c-prose > p[lang="en"] {
  font-size: var(--fs-body);
  line-height: var(--lh-en-body);
  color: var(--ink);
}
/* Demoted Malayalam is still Malayalam: --fs-small IS the 15px floor, and no
   line-height is declared here so base.css's `p[lang="ml"]` guard keeps it at
   1.7 or above. */
[data-locale="en"] .c-prose > p[lang="ml"] {
  font-size: var(--fs-small);
  color: var(--ink-2);
}

/* ── .c-timeline — a dated chronology ─────────────────────────────────────
   Marked up as an <ol>, because a chronology IS an ordered list; base.css
   already strips the list marker from any classed list. The spine is the
   list's own border and the stop-marker is each item's ::before, so the
   geometry costs no extra element and no image.

   The marker takes --radius-lg, which means it is a round stop in thaneer and
   ticket and a printed square in yathra — the same way every other component
   here lets the theme carry its geometry. Nothing about it is load-bearing:
   remove the spine and the marker and the datelines still carry the sequence,
   which is why neither needs a contrast certificate. */
.c-timeline {
  display: grid;
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  border-inline-start: var(--rule-w-strong) solid var(--accent);
}
.c-timeline__item {
  position: relative;
  max-inline-size: var(--measure);
  padding-inline-start: clamp(var(--sp-4), 3vw, var(--sp-6));
}
.c-timeline__item > * + * { margin-block-start: var(--sp-2); }
.c-timeline__item::before {
  content: "";
  position: absolute;
  /* centred ON the spine: half the marker's own width, plus half the rule */
  inset-inline-start: calc(-0.4375rem - var(--rule-w-strong) / 2);
  inset-block-start: 0.45em;
  inline-size: 0.875rem;
  block-size: 0.875rem;
  background: var(--surface-3);
  border: var(--rule-w-strong) solid var(--accent);
  border-radius: var(--radius-lg);
}
/* The dateline. Western Arabic numerals and tabular figures (Clause 2.2 #6).
   This element never holds Malayalam — it holds a <time> — which is the only
   reason it is allowed to be tracked at all; base.css's guard would neutralise
   the tracking anyway if any Malayalam were ever nested inside it. */
.c-timeline__year {
  font-family: var(--font-en);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--accent-text);
}

/* ══ §5 addendum — .c-search AS A FULL-PAGE FORM (grievance, enquiry) ══════
   The home page's journey search is ONE row of three text inputs. A real
   citizen form — /ml/sahayam/paraathi has nine controls — needs three things
   the card had never had to do, each of them measured as a defect first:

     1  a <textarea>. .c-search__field styles `input` (and, since the depot
        directory, `select`); a description box was still raw UA chrome —
        measured white plate, grey 1px border — sitting inside a themed card in
        all four themes. It takes the input's own plate, unchanged, and keeps
        `resize: vertical` from base.css. --fs-body also stops iOS Safari
        zooming the page on focus (it does that under 16px) and clears the 15px
        Malayalam floor for typed Malayalam prose.
     2  rhythm between two field ROWS. `gap` spaces items INSIDE one
        .c-search__fields; two consecutive rows measured 0px apart, so a date
        control touched the label of the row above it.
     3  a group heading INSIDE the card, so a nine-control form can be grouped
        (journey · what happened · about you). The reset gives every heading
        `margin: 0`, which collided with the controls on both sides.

   No new colour and no new token. The home page's .c-search is untouched: it
   has one field row, no textarea and no group heading, so none of this matches. */
.c-search__field textarea {
  width: 100%;
  min-height: calc(var(--tap) * 2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface);
  border: var(--rule-w-strong) solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: var(--lh-body);       /* typed Malayalam is body copy: >= 1.7 */
}
.c-search__field textarea::placeholder { color: var(--ink-2); opacity: 1; }
.c-search__field textarea:hover { border-color: var(--accent-text); }

.c-search__fields + .c-search__fields { margin-top: var(--sp-4); }

/* Subordinate to .c-search__head h2 by size and by the hairline above it: this
   is a divider with a name on it, not a second title. */
.c-search__grouph {
  margin: var(--sp-5) 0 var(--sp-3);
  padding-top: var(--sp-3);
  border-top: var(--rule-w) solid var(--rule);
  font-size: var(--fs-body);
  line-height: var(--lh-display);
  color: var(--accent-strong);
}
.c-search__grouph [lang="en"] {
  font-size: var(--fs-micro);        /* Latin only — the Malayalam sits above it */
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}


/* ══ 17 · .c-results / .c-result — THE JOURNEY-SEARCH RESULT ════════════════
   Added for /ml/yathra/thirayuka, which is audit finding P0-3: on the live site
   a passenger cannot ask "is there a bus from A to B?" anywhere at all.

   SYSTEM-level, not page-level. The same list is the answer on
   /ml/yathra/samayakramam (timetables), on the six destination pages ("which
   classes serve Munnar") and for the fare calculator's own results, so it lives
   here with everything else rather than in one page's <style> block.

   WHY IT IS NOT A TABLE. Eight facts per service is eight columns, and at 390px
   that puts the site's primary task permanently inside a horizontal scroller on
   the cheapest device its users own. Each result is therefore a card whose facts
   are a real <dl>: every value keeps its own label at every width, at every
   text-size step and for a screen reader, and the grid re-flows from two columns
   to four with no media query and no fixed breakpoint.

   REUSE, not reinvention: the four numbers a passenger actually compares
   (departure, arrival, duration, fare) are .c-stat, unchanged — the same data
   plate the corporation's statistics are set in. The booking deep link is
   .c-search__book, the "why am I being shown this" tag is .c-notice__chip, and
   the empty state's next actions are .c-tasks. This section adds the container,
   the class code and the two forgotten states, and nothing else.

   PLACEMENT. .c-result__code paints --ink-on-accent on --accent, a pair
   certified on the light bands (5.01:1 in livery, 7.6-9.4:1 in the other
   three). Keep the list on .c-band or .c-band--cream: inside .c-band--accent
   §1 re-points --accent to --highlight for a coloured ground, and the code
   would come out light-on-gold. No colour literal below, as everywhere else.
   ────────────────────────────────────────────────────────────────────────── */

/* .c-search rides UP over the hero by --hero-overlap. On an inner page there is
   no hero to ride over, so it is switched off explicitly rather than left to
   depend on --hero-overlap being undefined outside .c-search-band. */
.c-search--page { margin-top: 0; }

/* One result per row at every width. A two-column results list makes a
   passenger scan in two directions to compare two departure times. */
.c-results { display: grid; gap: var(--sp-4); }

.c-result {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--surface-3);
  /* the RULE separates the card, never the shadow: livery and yathra have
     --shadow: none */
  border: var(--rule-w) solid var(--rule);
  border-left: var(--rule-w-strong) solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
/* The "no exact match" set reads as offered rather than as matched. The dashed
   edge is the second signal; the first is the reason stated in words inside
   every one of these cards, because a border style alone would be meaning
   carried by presentation (WCAG 1.4.1). */
.c-result--nearby { border-left-style: dashed; }

/* Malayalam class name FIRST, Latin code second — the word is the meaning and
   the code is only shorthand. A passenger who does not read Latin can still
   tell an ഓർഡിനറി from a സൂപ്പർ ഫാസ്റ്റ്. */
.c-result__class {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-body);   /* it is a <p>: wrapped Malayalam keeps 1.7 */
  color: var(--accent-strong);
}
.c-result__code {
  padding: 0.1em 0.45em;
  background: var(--accent);
  border-radius: var(--radius);
  color: var(--ink-on-accent);
  font-family: var(--font-en);
  font-size: var(--fs-micro);    /* LATIN ONLY — the code is [lang="en"] */
  font-weight: 700;
  letter-spacing: 0.06em;        /* tracking: Latin ONLY */
  white-space: nowrap;
}

.c-result h3 {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-display);
  color: var(--ink);
}
.c-result h3 [lang="ml"] { display: block; font-weight: 750; }
.c-result h3 [lang="en"] {
  display: block;
  margin-top: 0.2em;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink-2);
}

/* The data plate: two columns at 390px, four on a desktop. .c-stat does all the
   typographic work, so these cells hold Western Arabic numerals in the Latin
   family with tabular figures — never Malayalam, whose conjuncts would drop to
   a fallback face inside .c-stat dd. */
.c-result__strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(50%, 7rem), 1fr));
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-3) 0;
  border-block: var(--rule-w) solid var(--rule);
}

/* The remaining facts — operating days, depot, via, the fare's arithmetic — as
   a definition list rather than one run-on caption line, so the label stays
   bound to its value both visually and in the accessibility tree. */
.c-result__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  gap: var(--sp-3);
  margin: 0;
}
.c-result__fact { min-width: 0; }
.c-result__fact dt {
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-result__fact dt [lang="en"] {
  display: block;
  font-size: var(--fs-micro);    /* Latin only — the Malayalam sits above it */
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
}
/* --lh-body, never --lh-display: this is a <dd> holding Malayalam place names,
   which wrap, so it must clear the 1.7 floor on its own account. */
.c-result__fact dd {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-body);
  color: var(--ink);
}

.c-result__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}
/* ONE primary action per result. The second action is a text link, not a second
   button: it sits outside a <p>, so WCAG 2.5.5 is met here rather than by
   base.css's inline exemption. */
.c-result__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: var(--tap);
  color: var(--accent-text);
  font-size: var(--fs-small);    /* holds Malayalam — never --fs-micro */
  font-weight: 650;
  line-height: var(--lh-body);
}
.c-result__link > svg { width: 1.1rem; height: 1.1rem; flex: 0 0 auto; }

/* ── THE EMPTY STATE — the one everybody forgets, and the one that decides
   whether a citizen searches again or gives up. It is not an error: it restates
   what was asked, says why nothing matched and offers the next actions. No
   accent rule and a dashed edge, so it can never be mistaken for a result. */
.c-results__empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: clamp(var(--sp-4), 3vw, var(--sp-6));
  background: var(--surface-3);
  border: var(--rule-w-strong) dashed var(--rule);
  border-radius: var(--radius-lg);
}
.c-results__empty > svg {
  width: clamp(2.25rem, 5vw, 3rem);
  height: clamp(2.25rem, 5vw, 3rem);
  flex: 0 0 auto;
  color: var(--accent-text);
}
.c-results__empty h3 {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-display);
  color: var(--ink);
}
.c-results__empty h3 [lang="ml"] { display: block; font-weight: 750; }
.c-results__empty h3 [lang="en"] {
  display: block;
  margin-top: 0.2em;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink-2);
}
.c-results__empty p {
  margin: 0;
  max-width: var(--measure);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
.c-results__empty p [lang="en"] { display: block; line-height: var(--lh-en-body); }
.c-results__empty .c-tasks { width: 100%; }

/* ── §8 addendum: an ICON inside .c-notice__more's action link.
   .c-notice__more a is already `display: inline-flex` with a `gap`, i.e. built to
   hold an icon beside its text — but it was the one icon-bearing component in
   this file with no size declared for it, because the home page only ever puts a
   text arrow there. An <svg> with no CSS size and no width/height attribute
   falls back to the replaced-element default and rendered ~60px tall next to
   15px text on /ml/sahayam/paraathi (measured in the 1440px capture). 1.15em is
   the same figure .c-notice__chip > svg already uses, so a phone or mail glyph
   beside a tel: link now matches the chip above it. */
.c-notice__more a > svg { width: 1.15em; height: 1.15em; flex: 0 0 auto; }

/* ── §1 addendum: THE SAMPLE BADGE INSIDE THE SAMPLE BAR ───────────────────
   Both elements wash themselves with --highlight — the badge at 26%, the bar it
   sits in at 20% — so nested, the two stack. In yathra, where --highlight is the
   brand orange rather than gold, --accent-text on that doubled ground measured
   4.03:1. The badge word is 13px bold, which is NORMAL text for WCAG 1.4.3, so
   the floor is 4.5:1 and 4.03 is a real failure. It is invisible to the repo
   gate because tools/gate-themes.js samples six pairs and this is not one of
   them; it was found by probing every pair on this page in all four themes.

   --accent-strong on the same stacked ground measures 5.12:1 in yathra, and it
   raises the other three themes too (livery 4.93 -> 5.90) — it is darker than
   --accent-text in every theme and in the high-contrast layer, so this can only
   improve a ratio, never lower one. Scoped to the NESTED case, so a badge on a
   plain card keeps the ink it was certified with, and declared as an addition
   rather than an edit to §1 so no page's existing certificate moves. */
/* SUPERSEDED. The reasoning above was correct for the chip as it then was: a 26%-alpha
   --highlight tint, whose contrast depended on the ground stacked behind it, so darkening
   the ink raised the ratio. The chip is now fully OPAQUE (see §.c-*__sample) with certified
   dark-on-highlight ink, so re-pointing its colour here no longer helps — it actively broke
   it, measuring 2.95:1 in yathra, because --accent-strong is a DARK red intended for light
   grounds and this ground is now orange. Removed rather than retuned: a self-contained chip
   should not have its ink overridden by where it sits.
.c-notices__samplebar .c-notice__sample {
  color: var(--accent-strong);
  border-color: var(--accent-strong);
} */

/* ── .c-result__why — WHY a nearby result is being offered ─────────────────
   The dashed edge on .c-result--nearby cannot be the only signal (WCAG 1.4.1),
   so every one of those cards states its reason in words. It borrowed
   .c-notice__chip first and that was wrong twice over, both visible in a 390px
   screenshot: .c-notice__chip is a ONE-WORD tag, so with a sentence in it the
   flex row wrapped and left the icon stranded alone on the first line; and
   .u-bi's parallel line is tracked uppercase, which is right for a two-word
   label and unreadable for a sentence. Here the icon is a fixed-size flex item
   beside the whole bilingual pair, so it can never be orphaned, and the English
   line is demoted by size and weight instead — the same way .c-notice h3 and
   .c-fares__aside already demote sentence-length English. */
.c-result__why {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  margin: 0;
  font-size: var(--fs-small);
  font-weight: 650;
  line-height: var(--lh-body);   /* a <p>: wrapped Malayalam keeps the 1.7 floor */
  color: var(--accent-strong);
}
.c-result__why > svg {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  margin-top: 0.3em;             /* optically centred on the first line */
}
.c-result__why [lang="en"] {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: normal;        /* undo .u-bi: this is a sentence, not a label */
  text-transform: none;
  line-height: var(--lh-en-body);
  color: var(--ink-2);
}
