/* ===========================================================================
   CAN-Agri components. `c-` = reusable on the sister site.
   EVERY radius here is uniform, by role, and fixed at all breakpoints (D-57).
   All [carry over] unless tagged otherwise.
   =========================================================================== */

/* ---- Buttons ------------------------------------------------------------
   Four styles. On light the primary is a teal fill; on the dark ground the
   primary becomes an ACCENT fill with teal text, which is the accent's best
   use and one of its two permitted appearances per screen (D-59).           */
/* One button language across the whole site (D-89). Jacqui: "this style must
   apply to all CTAs". So every button now carries the masthead treatment:
   Geist (Geist Mono until D-194), 600, uppercase, 0.1em tracking, and a STACKED label of one
   line per word group at 1.5 leading. Terminal does the same on every button,
   not only the header, which is where the idiom came from. The tiers are
   unchanged: fill and outline, each with its own on-dark variant, so contrast
   is not disturbed. */
.c-btn {
  display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: 0;
  /* THE SAME BOX AS THE MASTHEAD CLUSTER, D-166. Jacqui, 2026-09-08, holding a
     body button up against the cluster: "the padding here is very different
     from the cluster in the navbar. whats the standard?" Measured: the cluster
     was 8/16 padding, min-height 44, min-width 104; this was 8/24, min-height 48,
     no min-width, so the same label sat in a box 48 wide and 4 tall larger.
     D-89 unified the LABEL and never the container. The cluster is the standard
     because it is the one tuned against Terminal with Jacqui in the loop, so
     these three values are copied from .ca-cta, not chosen again. 44 clears the
     24px target minimum with room. */
  min-width: 104px; min-height: 44px;
  padding: var(--ca-space-2) var(--ca-space-4);
  border: 1px solid transparent;
  border-radius: var(--ca-r-control);
  font-family: var(--ca-font-label);
  font-size: var(--ca-size-btn);
  font-weight: var(--ca-weight-semibold);
  line-height: var(--ca-lh-btn);
  letter-spacing: var(--ca-track-eyebrow);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--ca-dur-fast) var(--ca-ease-out),
              color var(--ca-dur-fast) var(--ca-ease-out),
              border-color var(--ca-dur-fast) var(--ca-ease-out),
              scale var(--ca-dur-fast) var(--ca-ease-out);
}
/* The stacked word group. Shared with the masthead cluster so there is one
   implementation, and it animates transform only so nothing reflows. */
.c-btn__w, .ca-cta__w {
  display: block; line-height: var(--ca-lh-btn);
  transition: transform var(--ca-dur-fast) var(--ca-ease-out);
}
.c-btn__icon { width: 18px; height: 18px; flex: none; }

.c-btn--primary { background: var(--ca-teal); color: var(--ca-white); border-color: var(--ca-teal); }
/* The default body CTA was transparent and disappearing on white sections.
   Jacqui, 2026-09-08: "the default fill needs a percentage tint of our
   #c0d6d3, let's see how a 500 looks of that token", then "the CTA fill is too
   dark, needs to be half that tint". So it is the 250, half the 500, #e0ebe9.
   Measured: the teal label on it is 11.59:1, and the teal border stays so the
   control's boundary is 12.66:1 against white and 1.4.11 never depends on the
   fill. D-128, D-129. */
.c-btn--outline { background: var(--ca-tint-250); color: var(--ca-teal); border-color: var(--ca-teal); }
.ca-on-dark .c-btn--primary { background: var(--ca-accent); color: var(--ca-teal); border-color: var(--ca-accent); }
.ca-on-dark .c-btn--outline { background: transparent; color: var(--ca-white); border-color: rgba(255,255,255,.45); }
.c-btn--quiet { background: transparent; color: var(--ca-muted); border-color: var(--ca-border-control); }

@media (hover: hover) {
  /* Prototype enhancement. The developer may drop this guard, pre-approved.
     Two things on hover, per D-88: the tier steps, which carries the affordance
     on its own when motion is off, and the stacked words lift 2px with a 40ms
     stagger on each line after the first. */
  .c-btn--primary:hover { background: var(--ca-teal-900); border-color: var(--ca-teal-900); }
  .c-btn--outline:hover { background: var(--ca-teal); color: var(--ca-white); }
  .ca-on-dark .c-btn--primary:hover { background: var(--ca-accent-600); border-color: var(--ca-accent-600); }
  .ca-on-dark .c-btn--outline:hover { background: rgba(255,255,255,.10); border-color: var(--ca-white); }
  .c-btn--quiet:hover { background: var(--ca-soft); color: var(--ca-teal); }
  .c-btn:hover .c-btn__w { transform: translateY(-2px); }
  .c-btn:hover .c-btn__w + .c-btn__w { transition-delay: 40ms; }
}
/* PRESSED, on every control (D-258). Hover is guarded to mouse devices, so on
   a phone a tap had no visible answer at all. Pressing scales the control to
   97% and steps the fill to its hover tier, so the press reads with motion off.
   `scale` is its own property, so it composes with the play button's centring
   translate and the back-to-top's parking transform instead of replacing them;
   each control eases it inside its own transition list. */
:is(.c-btn, .ca-cta, .c-tab, .ca-film__play, .ca-menu-btn, .ca-totop):active { scale: .97; }
.c-btn--primary:active { background: var(--ca-teal-900); border-color: var(--ca-teal-900); }
.ca-on-dark .c-btn--primary:active { background: var(--ca-accent-600); border-color: var(--ca-accent-600); }
.c-btn--outline:active { background: var(--ca-teal); color: var(--ca-white); }
.ca-on-dark .c-btn--outline:active { background: rgba(255,255,255,.10); border-color: var(--ca-white); }
.c-btn--compact { min-height: 44px; padding: var(--ca-space-1) var(--ca-space-4); }
.c-btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }
.c-btn-pair { display: flex; flex-wrap: wrap; gap: var(--ca-space-3); }
/* Whatever follows a button group stands 24 off it, half the 48 the group stands
   off the head above, so a supporting line reads as belonging to the button. The
   home contact band's "Or reach us" line sat hard against the button at 0; 48 was
   tried and read too far (Jacqui, D-257). */
.c-btn-pair + * { margin-top: var(--ca-space-5); }

/* ---- Media: uniform radius, never a diagonal pair --------------------- */
.c-media { border-radius: var(--ca-r-media); overflow: hidden; background: var(--ca-teal); }
/* `picture` is the direct child wherever there is a srcset, so the height had
   to reach through it: the stretched Z media box grew and the image did not,
   leaving a teal band under the photograph. */
.c-media > picture { display: block; width: 100%; height: 100%; }
.c-media > img, .c-media > video,
.c-media > picture > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.c-media--3x2 { aspect-ratio: 3 / 2; }
.c-media--4x3 { aspect-ratio: 4 / 3; }
.c-media--1x1 { aspect-ratio: 1 / 1; }
.c-media--16x9 { aspect-ratio: 16 / 9; }

/* ---- The data layer: an SVG measurement overlay on media ---------------
   The line work and nodes are geometry; every LABEL is live text, so a screen
   reader can read it, it translates, it reflows, and a figure can be updated
   without re-rendering video (D-61). Node numbers are IDENTIFIERS of a real
   countable grid, never invented readings (D-62).                           */
.c-fig { position: relative; margin: 0; border-radius: var(--ca-r-media); overflow: hidden; background: var(--ca-teal); }
.c-fig__media { width: 100%; height: 100%; object-fit: cover; display: block; filter: brightness(.74) saturate(.88); }
.c-fig__layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.c-fig__line { fill: none; stroke: var(--ca-accent); stroke-width: 1.5; opacity: .85; }
.c-fig__node { fill: none; stroke: var(--ca-accent); stroke-width: 1.5; }
.c-fig__id {
  font-family: var(--ca-font-label); font-size: 14px; font-weight: 600;
  fill: var(--ca-accent); letter-spacing: .06em;
  paint-order: stroke; stroke: rgba(22, 48, 41,.85); stroke-width: 4px;
}
.c-fig__label {
  font-family: var(--ca-font-label); font-size: 12px; font-weight: 500;
  fill: var(--ca-white); letter-spacing: .1em; text-transform: uppercase;
  paint-order: stroke; stroke: rgba(22, 48, 41,.85); stroke-width: 4px;
}
.c-fig__caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--ca-space-11) var(--ca-space-5) var(--ca-space-4);
  background: linear-gradient(transparent, rgba(22, 48, 41,.94));
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase;
  color: var(--ca-tint);
}

/* ---- Video: poster, script-started, and a real pause control ----------- */
.c-video { position: relative; border-radius: var(--ca-r-media); overflow: hidden; background: var(--ca-teal); }
.c-video video { width: 100%; height: 100%; object-fit: cover; display: block; }
.c-video__pause {
  position: absolute; right: var(--ca-space-4); bottom: var(--ca-space-4); z-index: 3;
  min-height: 40px; display: inline-flex; align-items: center; gap: var(--ca-space-2);
  padding: var(--ca-space-2) var(--ca-space-4);
  background: rgba(22, 48, 41,.82); color: var(--ca-white);
  border: 1px solid rgba(255,255,255,.4); border-radius: var(--ca-r-control);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase; cursor: pointer;
}
.c-video__pause svg { width: 14px; height: 14px; }

/* ---- Cards: uniform 16, no accent corner ------------------------------- */
.c-card {
  background: var(--ca-white);
  border: 1px solid var(--ca-hairline);
  border-radius: var(--ca-r-media);
  padding: var(--ca-space-5);
}
.c-card--raised { box-shadow: var(--ca-shadow-card); }
.c-card > * + * { margin-top: var(--ca-space-3); }

/* ---- Marker for an unconfirmed fact ------------------------------------ */
.c-tbc {
  /* It must not wrap inside its own border, and it must not stop the page
     reflowing. Three attempts, recorded so the next person does not repeat
     them. As plain `inline-block` it took whatever line space was left, and on
     the narrower Z track that was about 30px, so it wrapped inside its border
     and rendered as a tall thin box five words deep. `white-space: nowrap`
     fixed that and broke A9 on all twelve pages, because a chip that cannot
     wrap forces horizontal overflow at 400 percent zoom. `display: block` with
     `fit-content` fixed THAT and broke it inside `.c-list`, where the list item
     is a grid: a block child became a grid item and landed in the narrow
     numbered column.
     `min-width: min(max-content, 100%)` was the fourth attempt and it silently
     did nothing: a CSS math function cannot contain an intrinsic sizing
     keyword, so the whole declaration was invalid and dropped. The lesson is
     that the browser does not tell you.
     What holds: `min-width: max-content` on its own, so the chip stays inline
     and simply cannot shrink below its own content, which pushes it to the next
     line whole instead of wrapping inside itself. Reflow is protected by
     dropping the min-width below 481, where the column is full width anyway and
     wrapping is the correct behaviour. D-137. */
  display: inline-block;
  min-width: max-content;
  max-width: 100%;
  padding: var(--ca-space-1) var(--ca-space-2);
  border: 1px solid var(--ca-accent-800);
  border-radius: var(--ca-r-input);
  background: var(--ca-white);
  color: var(--ca-accent-800);
  font-family: var(--ca-font-label);
  font-size: var(--ca-size-caption);
  font-weight: 500;
  letter-spacing: .04em;
}/* Below 481 the marker may wrap inside itself: the column is full width and
   a chip that cannot wrap would break reflow at 400 percent zoom. */
@media (max-width: 480px) { .c-tbc { min-width: 0; } }

.ca-on-dark .c-tbc { background: transparent; color: var(--ca-accent); border-color: var(--ca-accent); }

/* ---- Stats: Krub figure, mono label ----------------------------------- */
.c-stats { display: grid; gap: var(--ca-gap-col); }
.c-stats--3 { grid-template-columns: repeat(3, 1fr); }
.c-stats--4 { grid-template-columns: repeat(4, 1fr); }
.c-stat { border-top: 1px solid var(--ca-hairline); padding-top: var(--ca-space-4); }
.ca-on-dark .c-stat { border-top-color: rgba(192,214,211,.3); }
.c-stat__value {
  display: block;
  font-family: var(--ca-font-display);
  font-size: var(--ca-size-stat);
  /* BOLD, not medium. Jacqui, 2026-09-08: "sage figures must be a heavier
     weight". It also fixes the contrast problem in D-123: sage is 3.56:1 on
     white, which is legal for large text only, and bold at 18.66px or more
     COUNTS as large text. So the 480 exception that dropped the figure back to
     teal is no longer needed and has gone. D-127. */
  font-weight: var(--ca-weight-bold);
  line-height: var(--ca-lh-flat);
  letter-spacing: var(--ca-track-h2);
  color: var(--ca-text-figure);
  font-variant-numeric: tabular-nums;
}
.ca-on-dark .c-stat__value { color: var(--ca-white); }
.c-stat__unit {
  /* Valley Sans, and now much closer to the figure's own size. Jacqui,
     2026-09-08: "'%less' shouldn't be as smaller proportionally". It was
     20px against a 42px figure, a ratio of .48; at h3 it is 26 against 42,
     a ratio of .62. Same weight and same sage as the figure, because it is
     part of the figure rather than a note beside it. */
  font-family: var(--ca-font-display); font-size: var(--ca-size-h3);
  font-weight: var(--ca-weight-bold);
  color: var(--ca-text-figure);
  letter-spacing: var(--ca-track);   /* do NOT inherit the display tracking */
}
.ca-on-dark .c-stat__unit { color: var(--ca-tint); }
/* The 480 teal fallback from D-123 is GONE, because the figures are bold now:
   bold at 18.66px or more is large text, so sage's 3.56:1 is legal at every
   breakpoint. The smallest the figure gets is 23px and the unit 19px, both
   bold, both over the threshold. D-127. */
.c-stat__label {
  margin-top: var(--ca-space-3);
  /* Geist, not Geist Mono. Jacqui, 2026-09-08. These read as sentences rather
     than as labels, and the mono tracking of .06em was making short sentences
     look like machine output. Tracking goes back to normal with the family. */
  /* Up two sizes, 12 to 14, per Jacqui 2026-09-08: at 12 these sentences were
     smaller than the body copy they sit next to. */
  /* Body size, 14 to 16, Jacqui 2026-10-14 (D-205): at 14 they were still a step
     under the body copy, the same problem the 12 to 14 step was meant to fix. */
  font-family: var(--ca-font-text); font-size: var(--ca-size-body);
  line-height: var(--ca-lh-body); color: var(--ca-muted);
  /* Tim, 2026-09-22: "Line breaks should follow the semantic word concepts
     and keep on one line where possible." Balance evens the lines; the
     compounds and names in the copy carry non-breaking characters. */
  text-wrap: balance;
}
.ca-on-dark .c-stat__label { color: var(--ca-tint); }

/* ---- Momentum: dated evidence, not adjectives (D-60) ------------------ */
/* ---- Momentum: a spine that draws as you scroll ------------------------
   Measured off lightshiprv.com/technology's c-timeline rather than guessed: a
   vertical list, one node per item, a connector that draws in with a scroll
   --progress variable, text beside each node. Ours does the draw with a CSS
   scroll timeline, the same mechanism as the hero fold and for the same reason
   a time-based entrance was ruled out in D-135: the fill tracks the reader.
   No JavaScript. Where scroll timelines are unsupported, or motion is reduced,
   the spine is simply full. D-165.

   The node dots are not the "decorative status dot" tell: each marks a point
   on a dated sequence, which is real state, and it is the reference's own
   device. Radius is 50%, which A10 exempts as a percentage. */
.c-momentum { display: grid; gap: var(--ca-space-5); }
.c-momentum__note { margin: 0; }
.c-momentum__list {
  list-style: none; margin: 0; padding: 0;
  position: relative;
  display: grid; gap: 0;
}
/* the track, and the fill that draws down it */
.c-momentum__list::before,
.c-momentum__list::after {
  content: ""; position: absolute; left: 5px; top: 0; width: 2px;
  border-radius: 1px;
}
.c-momentum__list::before { bottom: 0; background: var(--ca-hairline); }
.c-momentum__list::after  { height: 100%; background: var(--ca-teal); }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes ca-spine-draw { from { height: 0; } to { height: 100%; } }
    .c-momentum__list::after {
      animation: ca-spine-draw linear both;
      animation-timeline: view();
      /* starts drawing as the list enters, complete by the time it is a third
         of the way up the screen, so the last node is filled while you are
         still reading it */
      animation-range: entry 0% cover 45%;
    }
  }
}
.c-moment {
  position: relative;
  display: grid; grid-template-columns: 96px 1fr; gap: var(--ca-space-5);
  padding: var(--ca-space-5) 0 var(--ca-space-5) var(--ca-space-6);
  align-items: baseline;
}
.c-moment + .c-moment { border-top: 1px solid var(--ca-hairline); }
/* the node, centred on the 2px spine at left 5px: 12px dot, so left 0 */
.c-moment::before {
  content: ""; position: absolute; left: 0; top: calc(var(--ca-space-5) + 0.35em);
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--ca-bg-tint); border: 2px solid var(--ca-teal);
}
.c-moment__when {
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase; color: var(--ca-teal);
  font-variant-numeric: tabular-nums;
}
.c-moment__what { font-size: var(--ca-size-body); color: var(--ca-ink); max-width: 52ch; }
.c-moment__what b { font-weight: var(--ca-weight-semibold); color: var(--ca-teal); }
@media (max-width: 767px) {
  .c-moment { grid-template-columns: 1fr; gap: var(--ca-space-2); }
}

/* ---- Tabs -------------------------------------------------------------- */
.c-tabs__list { display: flex; flex-wrap: wrap; gap: var(--ca-space-2); margin-bottom: var(--ca-space-5); }   /* 48 to 24, D-285 */
/* A tabbed block sits closer under its section head: 24, half the 48 a head keeps above other content
   (Jacqui, 2026-10-26, "the spacing here should be halved", D-285). */
.ca-head:has(+ [data-tabs]) { margin-bottom: var(--ca-space-5); }
.c-tab {
  padding: var(--ca-space-3) var(--ca-space-4);
  border: 1px solid var(--ca-border-control);
  border-radius: var(--ca-r-control);
  background: transparent;
  color: var(--ca-muted);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase;
  cursor: pointer; min-height: 44px;
  transition: background-color var(--ca-dur-base) var(--ca-ease-out), color var(--ca-dur-base) var(--ca-ease-out), scale var(--ca-dur-fast) var(--ca-ease-out);
}
.c-tab[aria-selected="true"] { background: var(--ca-teal); color: var(--ca-white); border-color: var(--ca-teal); }
.c-tabs__panel[hidden] { display: none; }
/* A new panel settles 8px into place so the change reads as a change (D-258).
   Movement only, never a fade: the house rule is that nothing meant to be read
   is ever parked at opacity 0 (D-64). Only once the tabs are wired, so the
   first panel does not move on load. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes ca-settle { from { transform: translateY(var(--ca-space-2)); } to { transform: none; } }
  [data-tabs].is-switched .c-tabs__panel:not([hidden]) { animation: ca-settle var(--ca-dur-base) var(--ca-ease-out); }
}

/* ---- Accordion --------------------------------------------------------- */
.c-acc { border-top: 1px solid var(--ca-hairline); }
.c-acc__item { border-bottom: 1px solid var(--ca-hairline); }
.c-acc__head {
  width: 100%; display: flex; align-items: baseline; gap: var(--ca-space-4);
  padding: var(--ca-space-5) 0; background: none; border: 0; cursor: pointer; text-align: left;
  font-family: var(--ca-font-display); font-size: var(--ca-size-h4);
  font-weight: var(--ca-weight-h3); letter-spacing: var(--ca-track-h4); color: var(--ca-teal);
}
.c-acc__chevron { width: 20px; height: 20px; flex: none; margin-left: auto; color: var(--ca-teal);
  transition: transform var(--ca-dur-base) var(--ca-ease-out); }
.c-acc__item.is-open .c-acc__chevron { transform: rotate(180deg); }
.c-acc__panel { padding: 0 0 var(--ca-space-6); }   /* no number column since D-291, so the text aligns under the title */
.c-acc__panel[hidden] { display: none; }
/* A measure on the panel text: in one column (1024 and down) the panel is the
   full content width and an open item ran 94 characters a line. 56ch sets about
   70 in Geist, inside A11's 45 to 75 (D-210). */
.c-acc__panel p { max-width: 56ch; }

/* ---- Table: the CAN-Agri column is the one dark column ---------------- */
.c-table-wrap {
  overflow-x: auto; overflow-y: hidden;
  border: 1px solid var(--ca-hairline);
  border-radius: var(--ca-r-media);
  background: var(--ca-white);
}
/* separate, not collapse: a collapsed table's cells cannot take a radius, and the bracket's bottom-right
   corner has to follow the frame's rounded corner or the frame clips its two 2px rules off (D-239). With
   no spacing and no side borders on the ordinary cells, the grid looks the same. */
.c-table { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 780px; }
/* The caption is for screen readers only. Jacqui, 2026-10-26: "remove this whole line and the row it's in
   from the table" (D-296). It stays in the markup, visually hidden, because it names the table. */
.c-table caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.c-table th, .c-table td {
  text-align: left; padding: var(--ca-space-4) var(--ca-space-5);
  border-bottom: 1px solid var(--ca-hairline); font-size: var(--ca-size-small);
}
.c-table thead th {
  background: var(--ca-soft); color: var(--ca-teal);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  font-weight: 500; letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase;
  vertical-align: bottom;
}
.c-table th[scope="row"] { font-weight: var(--ca-weight-semibold); color: var(--ca-teal); }
/* The CAN-Agri column is BRACKETED, not filled dark. Jacqui, 2026-09-08: "try
   find another way to highlight the can-agri cells instead of that dark teal
   fill." A solid teal block down one column of a light table reads as a
   different object dropped into the grid, and it forced the marks inside it
   onto the accent, which is 1.32:1 at best on anything light.
   Instead: the palest tint step as a fill, a continuous 2px teal rule down both
   sides and across the top and bottom, and the strongest text weight. With
   border-collapse the side rules meet, so the column reads as one card standing
   slightly forward of the table rather than as a hole cut in it. D-149. */
.c-table .is-us, .c-table thead .is-us {
  background: var(--ca-accent-100);   /* was --ca-tint-250 until D-239: Jacqui, "let's try a light tint of the accent colour here" */
  color: var(--ca-ink);
  font-weight: var(--ca-weight-semibold);
  border-left: 2px solid var(--ca-teal);
  border-right: 2px solid var(--ca-teal);
}
/* The row rules have to change colour inside this column, and the reason is a
   coincidence in the palette: --ca-tint-250 and --ca-hairline are BOTH #e0ebe9,
   noted when the tint ramp went in. So the 1px hairline between rows was still
   there and was drawing the fill colour onto the fill. Jacqui: "don't lose the
   lines inbetween the rows on desktop." Inside the column they draw in the 500
   step instead, which is the next tone down from the fill and sits at the same
   1.25:1 against it as the hairline does against white. D-151. Since D-239 the fill is
   the accent's 25% screen, no longer the hairline's colour, so the override is gone and the ordinary hairline
   runs straight across the table, through the column, at 1.20:1 on the fill. */
.c-table thead .is-us { color: var(--ca-teal); border-top: 2px solid var(--ca-teal); background: var(--ca-accent-150); }   /* head one step over the body, the table's own pattern (D-249) */
.c-table tbody tr:last-child .is-us { border-bottom: 2px solid var(--ca-teal); border-bottom-right-radius: var(--ca-r-media); }
/* Its top-right corner too, now the caption row is gone and the head row meets the frame's rounded corner, which
   clipped the 2px rules off (D-314). */
.c-table thead .is-us { border-top-right-radius: var(--ca-r-media); }
.c-mark { display: inline-flex; align-items: center; gap: var(--ca-space-2); color: var(--ca-ink); }
.c-mark__dot { width: 12px; height: 12px; border-radius: 50%; flex: none; border: 1.5px solid var(--ca-grade); }
.c-mark--full .c-mark__dot { background: var(--ca-grade); }
.c-mark--half .c-mark__dot { background: linear-gradient(90deg, var(--ca-grade) 50%, transparent 50%); }
/* The marks in that column go TEAL, not accent. On the old dark fill the accent
   was the only thing that read; on a light fill it measures 1.32:1 and would be
   the weakest mark in the table rather than the strongest. Teal is 12.66:1. */
.c-table .is-us .c-mark { color: var(--ca-teal); }
.c-table .is-us .c-mark__dot { border-color: var(--ca-teal); }
.c-table .is-us .c-mark--full .c-mark__dot { background: var(--ca-teal); }
.c-table .is-us .c-mark--half .c-mark__dot { background: linear-gradient(90deg, var(--ca-teal) 50%, transparent 50%); }

/* ---- The table on a phone: one card per measure -------------------------
   Jacqui, 2026-09-08: "we need to make table on the home page mobile friendly.
   Are you able to collapse the columns."

   Four methods across five columns cannot be read on a 390px screen. It used to
   be a 780px table inside a horizontal scroller, which passed every check and
   asked the reader to swipe a table sideways to compare anything.

   Below 768 each ROW becomes a card: the measure is the card's title and the
   four methods are label and value pairs underneath, the column name coming
   from each cell's own data-label. Nothing is hidden and nothing scrolls.

   The tables carry EXPLICIT ARIA ROLES for this. Changing `display` on table
   parts strips table semantics out of the accessibility tree in every engine,
   so role="table", "rowgroup", "row", "columnheader", "rowheader" and "cell"
   are in the markup to put them back. That is the documented fix, not a
   flourish. D-150. */
@media (max-width: 767px) {
  .c-table-wrap { overflow-x: visible; border: 0; background: none; border-radius: 0; }
  /* The caption is NOT in this list since D-296: it is visually hidden, and width: auto here would undo its
     1px box. */
  .c-table, .c-table thead, .c-table tbody, .c-table tr,
  .c-table th, .c-table td {
    display: block; width: auto;
  }
  .c-table { min-width: 0; }
  .c-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .c-table tbody tr {
    background: var(--ca-white);
    border: 1px solid var(--ca-hairline);
    border-radius: var(--ca-r-media);
    padding: var(--ca-space-5);
    margin-bottom: var(--ca-space-5);
  }
  .c-table tbody tr:last-child { margin-bottom: 0; }
  .c-table th[scope="row"] {
    padding: 0 0 var(--ca-space-4);
    border-bottom: 1px solid var(--ca-hairline);
    font-family: var(--ca-font-display); font-size: var(--ca-size-h4);
    font-weight: var(--ca-weight-h3); color: var(--ca-teal);
  }
  .c-table td {
    padding: var(--ca-space-4) 0 0;
    border-bottom: 0;
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--ca-space-4);
    align-items: baseline;
  }
  .c-table td::before {
    content: attr(data-label);
    font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
    letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase;
    color: var(--ca-muted);
  }
  /* The bracket becomes one left rule: a card has no column sides to bracket. */
  .c-table .is-us {
    background: var(--ca-accent-125);   /* 5% read too faint as a card row on a phone: 10%, still under the 15% head (D-255) */
    border-left: 2px solid var(--ca-teal); border-right: 0; border-top: 0;
    padding-left: var(--ca-space-4);
    margin-top: var(--ca-space-4);
  }
  .c-table tbody tr:last-child .is-us { border-bottom: 0; border-bottom-right-radius: 0; }
  .c-table .is-us::before { color: var(--ca-teal); }
}

/* ---- Chips and lists --------------------------------------------------- */
.c-chips { display: flex; flex-wrap: wrap; gap: var(--ca-space-2); }
.c-chip {
  padding: var(--ca-space-2) var(--ca-space-4);
  border: 1px solid var(--ca-hairline); border-radius: var(--ca-r-control);
  background: var(--ca-white);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: .06em; text-transform: uppercase; color: var(--ca-teal);
}
.c-chip--roadmap { color: var(--ca-muted); background: var(--ca-soft); }
.c-list { list-style: none; padding: 0 0 0 var(--ca-space-5); margin: 0; display: grid; gap: var(--ca-space-2); }   /* bullets indented 24, D-288 */   /* 12 to 8 between items, Jacqui 2026-10-21 (D-253) */
/* Tim, 2026-09-22: "Spacing." The list sat flush under the lead because this
   file loads after base.css and the margin: 0 above, at equal specificity,
   cancelled the stack rhythm `.ca-stack > * + *`. Restored here explicitly. */
.ca-stack > .c-list { margin-top: var(--ca-space-5); }
/* SQUARE BULLETS, not numbers (Jacqui, 2026-10-26, "change all number lists to square bullet points", D-287,
   after Annika: numbers signal a sequence and these lists are not one). A 6px square in sage, centred on the
   first line of its item by translate, which is not a margin, so the spacing scale is untouched. */
.c-list li {
  position: relative; padding-left: var(--ca-space-4);
  color: var(--ca-ink); max-width: var(--ca-measure);
}
/* Positioned, not a grid column: an item's text and any marker inside it flow as one block. */
.c-list li::before {
  content: ""; position: absolute; left: 0; top: 0; width: 6px; height: 6px; background: var(--ca-sage);
  translate: 0 calc(.5lh - 3px);
}
.ca-on-dark .c-list li { color: var(--ca-tint); }
.ca-on-dark .c-list li::before { background: var(--ca-accent); }

/* ---- Form -------------------------------------------------------------- */
.c-form { display: grid; gap: var(--ca-space-5); max-width: 620px; }
.c-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ca-space-5); }
/* Each field in a row spans the row's three tracks (label, control, error) through a subgrid, so the
   controls line up even when one label wraps, as "Company or organisation" does at 1280 (D-233). */
.c-form__row > .c-field { grid-row: span 3; grid-template-rows: subgrid; row-gap: 0; }
/* The subgrid always holds the error track, so the 8px between label, control and error moves onto the label
   and the error itself: a hidden error then takes no space at all. */
.c-form__row > .c-field > .c-field__label { margin-bottom: var(--ca-space-2); }
.c-form__row > .c-field > .c-field__error { margin-top: var(--ca-space-2); }
.c-field { display: grid; gap: var(--ca-space-2); }
.c-field__label {
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase; color: var(--ca-muted);
}
.c-field__req { color: var(--ca-error); }
.c-input {
  width: 100%; min-height: 48px;
  padding: var(--ca-space-3) var(--ca-space-4);
  background: var(--ca-white);
  border: 1px solid var(--ca-border-control);
  border-radius: var(--ca-r-input);
  font-family: var(--ca-font-text); font-size: var(--ca-size-body); color: var(--ca-ink);
}
textarea.c-input { min-height: 132px; resize: vertical; }
/* Inputs and the select share one fixed height, so a row of two lines up box for box (D-233). */
input.c-input, select.c-input { height: 48px; }
/* The select drops the browser's own drawing, which sets its text at a different inset, adds a system arrow
   and, in Safari, ignores the padding and height altogether. Drawn like an input instead, with the chevron
   in ink. While the prompt is selected the field is :invalid (required, empty value), so it reads in the
   muted placeholder colour; the options themselves stay ink (D-233). */
select.c-input {
  -webkit-appearance: none; appearance: none;
  padding-right: var(--ca-space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232e3435' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--ca-space-4) center; background-size: 16px 16px;
}
select.c-input:invalid { color: var(--ca-muted); }
select.c-input option { color: var(--ca-ink); }
/* A plain list of links, no markers, for the social links in Reach us directly (D-234). */
/* margin-top is left to the stack's rhythm (.ca-stack > * + *, the D-195 trap); only the UA bottom margin goes.
   No gap: each link sits on the body line height, the same rhythm as the phone and email lines above it. */
.ca-linklist { list-style: none; margin-bottom: 0; padding: 0; }
.c-input:focus-visible { border-color: var(--ca-teal); outline: 3px solid var(--ca-teal); outline-offset: 1px; }
.c-field.is-invalid .c-input { border-color: var(--ca-error); }
.c-field__error {
  display: none; align-items: center; gap: var(--ca-space-2);
  color: var(--ca-error); font-size: var(--ca-size-small);
}
.c-field.is-invalid .c-field__error { display: flex; }
.c-field__error svg { width: 16px; height: 16px; flex: none; }
.c-check { display: grid; grid-template-columns: 24px 1fr; gap: var(--ca-space-3); align-items: start; }
.c-check input {
  width: 24px; height: 24px; margin: 0;
  border: 1px solid var(--ca-muted); border-radius: var(--ca-r-input);
  color: var(--ca-ink); accent-color: var(--ca-teal);
}
.c-check label { font-size: var(--ca-size-small); color: var(--ca-ink); }
.c-form__success {
  padding: var(--ca-space-5); background: var(--ca-soft);
  border: 1px solid var(--ca-teal); border-radius: var(--ca-r-media); max-width: 620px;
}
.c-form__success[hidden] { display: none; }

@media (max-width: 1024px) { .c-stats--3 { grid-template-columns: 1fr; } }
/* Four stats stay two across below 1024 instead of dropping to one column:
   Jacqui, 2026-10-14, "the bottom 2 stats stack left as soon as the breakpoint
   changes, so that it becomes 2 on a row" (D-209). One column only on a small
   phone, where half the width is too narrow for a figure and its label. */
@media (max-width: 1024px) { .c-stats--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .c-stats--4 { grid-template-columns: 1fr; } }
@media (min-width: 1025px) and (max-width: 1280px) { .c-stats--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 767px) {
  .c-form__row { grid-template-columns: 1fr; }
  .c-moment { grid-template-columns: 1fr; gap: var(--ca-space-2); }
  .c-acc__panel { padding-left: 0; }
  .c-table th, .c-table td { padding: var(--ca-space-3) var(--ca-space-4); }
}

/* ---- Calculator: agronomic outputs only, permanently labelled -------- */
.c-calc { display: grid; grid-template-columns: 5fr 7fr; gap: var(--ca-gutter); align-items: start; }
.c-calc__badge {
  display: inline-block; margin-bottom: var(--ca-space-5);
  padding: var(--ca-space-2) var(--ca-space-4);
  border: 1px solid var(--ca-accent); border-radius: var(--ca-r-control);
  color: var(--ca-accent); font-family: var(--ca-font-label);
  font-size: var(--ca-size-caption); letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase;
}
.c-calc__control { margin-bottom: var(--ca-space-6); }
.c-calc__label {
  display: block; margin-bottom: var(--ca-space-3);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: var(--ca-track-eyebrow); text-transform: uppercase; color: var(--ca-tint);
}
.c-calc__value {
  font-family: var(--ca-font-display); font-size: var(--ca-size-h4);
  color: var(--ca-white);
  letter-spacing: var(--ca-track-h4);   /* do not inherit the eyebrow tracking */
  text-transform: none;
}
.c-calc input[type="range"] { width: 100%; min-height: 44px; margin: 0; accent-color: var(--ca-accent); }
.c-calc select {
  width: 100%; min-height: 48px; padding: var(--ca-space-3) var(--ca-space-4);
  background: var(--ca-teal-900); color: var(--ca-white);
  border: 1px solid rgba(255,255,255,.3); border-radius: var(--ca-r-input);
  font-family: var(--ca-font-text); font-size: var(--ca-size-body);
}
.c-calc__outputs { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ca-space-4); }
.c-calc__out { padding: var(--ca-space-5); border: 1px solid rgba(255,255,255,.18); border-radius: var(--ca-r-media); }
.c-calc__num {
  display: block; font-family: var(--ca-font-display); font-size: var(--ca-size-h2);
  font-weight: var(--ca-weight-h2); letter-spacing: var(--ca-track-h2);
  line-height: var(--ca-lh-flat); color: var(--ca-white); font-variant-numeric: tabular-nums;
}
.c-calc__unit { font-family: var(--ca-font-label); font-size: var(--ca-size-lead); letter-spacing: var(--ca-track); color: var(--ca-tint); }
.c-calc__key {
  margin-top: var(--ca-space-3); font-family: var(--ca-font-label);
  font-size: var(--ca-size-caption); letter-spacing: .06em; color: var(--ca-tint); line-height: 1.5;
}
.c-calc__note { margin-top: var(--ca-space-5); font-size: var(--ca-size-small); color: var(--ca-tint); max-width: 48ch; }
.c-bar { margin: var(--ca-space-5) 0 0; }
.c-bar__head {
  display: flex; justify-content: space-between; gap: var(--ca-space-4);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption);
  letter-spacing: .06em; color: var(--ca-tint); margin-bottom: var(--ca-space-2);
}
.c-bar__track { height: 8px; background: rgba(255,255,255,.14); border-radius: var(--ca-r-input); overflow: hidden; }
.c-bar__track + .c-bar__track { margin-top: var(--ca-space-2); }
.c-bar__fill { height: 100%; border-radius: var(--ca-r-input); transition: width var(--ca-dur-slow) var(--ca-ease-out); }
.c-bar__fill--conv { background: var(--ca-tint); width: var(--fill, 100%); }
.c-bar__fill--ca { background: var(--ca-accent); width: var(--fill, 10%); }
.c-legend {
  display: flex; flex-wrap: wrap; gap: var(--ca-space-5); margin-top: var(--ca-space-4);
  font-family: var(--ca-font-label); font-size: var(--ca-size-caption); letter-spacing: .06em; color: var(--ca-tint);
}
.c-legend span { display: inline-flex; align-items: center; gap: var(--ca-space-2); }
.c-legend i { width: 10px; height: 10px; border-radius: var(--ca-r-input); }
.c-legend i.is-conv { background: var(--ca-tint); }
.c-legend i.is-ca { background: var(--ca-accent); }

@media (max-width: 1024px) { .c-calc { grid-template-columns: 1fr; } }
@media (max-width: 480px) { .c-calc__outputs { grid-template-columns: 1fr; } }

/* ---- Feature card carousel (D-170) ------------------------------------
   Lightship's technology-page device: landscape cards two to a view with the
   third peeking, prev and next buttons and dots beneath, a plus on each card
   that opens a modal carrying the paragraph. Native scroll-snap does the
   carousel; the buttons only call scrollBy. No autoplay, so 2.2.2 never
   arises. The eyebrow and statement sit BELOW the image on the card surface,
   not over it: four stills with white type over them is four B7 samples, and
   the hero already carries the one 1.69:1 judgement call (D-122). */
.c-carousel { position: relative; }
.c-carousel__track {
  display: flex; gap: var(--ca-space-4);
  list-style: none; margin: 0; padding: 0;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  scroll-padding-inline: 0;
}
.c-carousel__track::-webkit-scrollbar { display: none; }
.c-feature { flex: 0 0 calc((100% - var(--ca-space-4)) / 2); scroll-snap-align: start; margin: 0; padding: 0; }
@media (max-width: 767px) { .c-feature { flex-basis: 86%; } }
.c-feature__card {
  display: flex; flex-direction: column; height: 100%;
  border-radius: var(--ca-r-media); overflow: hidden;
  background: var(--ca-tint-250);
}
.c-feature .c-media { border-radius: 0; flex: none; }
.c-feature__body {
  display: grid; grid-template-columns: 1fr auto; gap: var(--ca-space-4); align-items: end;
  padding: var(--ca-space-5); flex: 1;
}
.c-feature__body .ca-eyebrow { margin-bottom: var(--ca-space-1); }   /* 8 to 4, D-202 */
.c-feature__line { margin: 0; }
.c-feature__more,
.c-carousel__btn,
.c-dialog__close {
  width: 44px; height: 44px; padding: 0;
  display: grid; place-items: center;
  border-radius: var(--ca-r-control); cursor: pointer;
  transition: background-color var(--ca-dur-base) var(--ca-ease-out), color var(--ca-dur-base) var(--ca-ease-out), border-color var(--ca-dur-base) var(--ca-ease-out);
}
.c-feature__more { border: 0; background: var(--ca-teal); color: var(--ca-white); }
.c-carousel__btn, .c-dialog__close { border: 1px solid var(--ca-border-control); background: var(--ca-white); color: var(--ca-teal); }
.c-carousel__btn[disabled] { opacity: .4; cursor: default; }
@media (hover: hover) {
  .c-carousel__btn:not([disabled]):hover, .c-dialog__close:hover { border-color: var(--ca-teal); }
}
.c-carousel__nav { display: flex; align-items: center; gap: var(--ca-space-2); margin-top: var(--ca-space-6); }
.c-carousel__dots { display: flex; gap: var(--ca-space-2); margin-left: var(--ca-space-4); }
/* An 8px box with the 8px control radius is a circle without a 50% radius outside the set. */
.c-carousel__dot { width: 8px; height: 8px; border-radius: var(--ca-r-control); background: var(--ca-hairline); transition: background-color var(--ca-dur-base) var(--ca-ease-out); }
.c-carousel__dot.is-current { background: var(--ca-teal); }
/* Without JavaScript the buttons have nothing to do and the dialogs render
   inline under the cards, so every word is still on the page (A18). The flag
   is the script's own `has-dialogs` on <html>, not the reveal code's is-ready,
   which is deliberately absent under reduced motion. */
html:not(.has-dialogs) .c-feature__more, .c-carousel:not(.is-ready) .c-carousel__nav, html:not(.has-dialogs) .c-dialog__close { display: none; }

/* ---- Dialog (D-170) ----------------------------------------------------- */
.c-dialog {
  border: 0; padding: 0; margin: auto;
  width: min(560px, calc(100% - 2 * var(--ca-gutter)));
  border-radius: var(--ca-r-panel); background: var(--ca-white); color: inherit;
  box-shadow: var(--ca-shadow-media);
}
.c-dialog::backdrop { background: rgba(22, 48, 41, .6); }
.c-dialog__in { position: relative; padding: var(--ca-space-7); }
.c-dialog__in > * + * { margin-top: var(--ca-space-4); }
.c-dialog__in > .ca-eyebrow + h3 { margin-top: var(--ca-space-1); padding-right: var(--ca-space-9); }
.c-dialog__close { position: absolute; top: var(--ca-space-4); right: var(--ca-space-4); }
@media (prefers-reduced-motion: no-preference) {
  @keyframes ca-dialog-in { from { transform: translateY(var(--ca-space-4)); } to { transform: none; } }
  .c-dialog[open] { animation: ca-dialog-in var(--ca-dur-slow) var(--ca-ease-out); }
}
html:not(.has-dialogs) .c-dialog {
  display: block; position: static; width: auto; box-shadow: none;
  margin-top: var(--ca-space-6); border: 1px solid var(--ca-hairline);
}

