/* ==========================================================================
   NATFISH V2
   National Fishermen Producers Co-operative Society Ltd.
   No build step, no external dependencies.
   ==========================================================================

   EVERY :hover RULE IN THIS FILE SITS INSIDE @media (hover: hover).
   Keep it that way when adding one.

   The reason is the double tap the client reported. On a touch device with no
   real pointer - iOS Safari most of all - the first tap on an element that has
   hover styles is spent applying them, and only the second tap activates the
   control. The visitor experiences a link or a gallery photograph that ignores
   the first touch. Gating the hover styles on a pointer that can actually
   hover removes the phantom hover state, and with it the wasted tap.

   Nothing is lost on a desktop: (hover: hover) is true for a mouse or a
   trackpad, so every hover style behaves exactly as before. It is false for a
   finger, where a hover style could never be seen anyway.

   `taps.js` asserts one tap per control on a touch device and that no hover
   rule survives when the pointer cannot hover.
   ========================================================================== */

:root {
  /* Palette: deep Caribbean navy, ocean teal, turquoise, white.
     Coral is a restrained accent only, never a section fill. */
  --navy-900: #03192a;
  --navy-800: #052b45;
  --navy-700: #0a3c5c;
  --teal-700: #0b6675;
  --teal-600: #0e7c8b;
  --turq-500: #22a7bc;
  --turq-300: #7fd7e4;
  --coral: #d9503a;

  --sand: #f4f8fa;
  --sand-200: #e5eef2;
  --white: #ffffff;

  --ink: #10293a;
  --ink-soft: #4a6376;
  --ink-onDark: rgba(255, 255, 255, 0.82);
  --line: rgba(16, 41, 58, 0.14);
  --line-onDark: rgba(255, 255, 255, 0.16);

  --shadow-sm: 0 2px 8px rgba(5, 43, 69, 0.06);
  --shadow-md: 0 14px 38px rgba(5, 43, 69, 0.1);
  --shadow-lg: 0 28px 70px rgba(5, 43, 69, 0.16);

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;

  /* Bitter is a slab serif: sturdy and editorial, and it reads as a working
     institution rather than a hospitality brand. Source Sans 3 carries every
     word a visitor actually reads. Both self-hosted, see css/fonts.css. */
  --font-display: "Bitter", Georgia, "Times New Roman", serif;
  --font-body: "Source Sans 3", "Segoe UI", Arial, sans-serif;

  --container: 1200px;
  --gutter: clamp(1.15rem, 4vw, 2.5rem);
  --section-y: clamp(3.75rem, 8vw, 7rem);
  --header-h: 88px;
}

/* --------------------------------------------------------------- base -- */

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

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header. */
  scroll-padding-top: calc(var(--header-h) + 12px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  /* Source Sans 3 runs a touch smaller than the old system stack at the same
     px, so the base size and measure are nudged up to compensate. */
  font-size: 1.09rem;
  line-height: 1.62;
  color: var(--ink);
  background: var(--white);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

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

img {
  height: auto;
}

/* Slab serifs carry more ink per character than the old grotesque, so the
   tracking is far less negative and the leading is a little looser than the
   sans-serif settings these replaced. */
h1,
h2,
h3,
h4 {
  margin: 0 0 0.5em;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.008em;
  color: var(--navy-800);
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.05rem, 4.9vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: -0.014em;
}

h2 {
  font-size: clamp(1.55rem, 3.2vw, 2.3rem);
  line-height: 1.16;
  letter-spacing: -0.011em;
}

h3 {
  font-size: clamp(1.12rem, 1.75vw, 1.3rem);
  font-weight: 650;
  line-height: 1.32;
  letter-spacing: -0.004em;
}

h4 {
  font-weight: 650;
}

p {
  margin: 0 0 1.1em;
}

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

a {
  color: var(--teal-700);
  text-underline-offset: 3px;
}


@media (hover: hover) {
  a:hover {
    color: var(--navy-800);
  }
}


ul {
  margin: 0 0 1.1em;
  padding-left: 1.15rem;
}

li {
  margin-bottom: 0.4rem;
}

strong {
  font-weight: 650;
  color: var(--navy-800);
}

:focus-visible {
  outline: 3px solid var(--turq-500);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -110%);
  z-index: 999;
  background: var(--navy-800);
  color: var(--white);
  padding: 0.85rem 1.5rem;
  border-radius: 0 0 var(--radius) var(--radius);
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.18s ease;
}

.skip-link:focus {
  transform: translate(-50%, 0);
  color: var(--white);
}

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

/* ---------------------------------------------------------- structure -- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow {
  max-width: 880px;
}

.section {
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: clamp(2.75rem, 5.5vw, 4.5rem);
}

.section--sand {
  background: var(--sand);
}

.section--navy {
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(34, 167, 188, 0.24), transparent 58%),
    linear-gradient(165deg, var(--navy-800) 0%, var(--navy-900) 100%);
  color: var(--ink-onDark);
}

.section--navy h2,
.section--navy h3 {
  color: var(--white);
}

.section--navy a {
  color: var(--turq-300);
}


@media (hover: hover) {
  .section--navy a:hover {
    color: var(--white);
  }
}


.section-head {
  max-width: 60ch;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.eyebrow {
  display: block;
  /* Raised from 0.85rem. The trailing dash used to give the eyebrow visual
     weight and a little optical space; without it the line needs the gap
     itself, or it reads as crowding the heading. */
  margin-bottom: 0.7rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--teal-600);
}

.section--navy .eyebrow {
  color: var(--turq-300);
}

/* The 26px dash that used to trail every eyebrow is gone, at the client's
   request, along with the wave glyph and the hairline that sat above section
   heads. Headings now carry no ornament at all - the eyebrow's letter-spaced
   uppercase and the heading beneath it do the work. Do not put a decorative
   rule back beside or above a title. */

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  color: var(--ink-soft);
  max-width: 62ch;
}

.section--navy .lede {
  color: var(--ink-onDark);
}

.note {
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------ buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 50px;
  padding: 0.8rem 1.65rem;
  border: 1.5px solid transparent;
  border-radius: 7px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.18s ease, background-color 0.18s ease,
    border-color 0.18s ease, box-shadow 0.18s ease, color 0.18s ease;
}


@media (hover: hover) {
  .btn:hover {
    transform: translateY(-1px);
  }
}


.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: var(--teal-600);
  border-color: var(--teal-600);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}


@media (hover: hover) {
  .btn--primary:hover {
    background: var(--teal-700);
    border-color: var(--teal-700);
    color: var(--white);
    box-shadow: var(--shadow-md);
  }
}


.btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--white);
}


@media (hover: hover) {
  .btn--ghost:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: var(--white);
    color: var(--white);
  }
}


.btn--outline {
  background: transparent;
  border-color: var(--line);
  color: var(--navy-800);
}


@media (hover: hover) {
  .btn--outline:hover {
    border-color: var(--teal-600);
    color: var(--teal-700);
    background: rgba(14, 124, 139, 0.05);
  }
}


.btn--block {
  width: 100%;
}

.btn--sm {
  min-height: 44px;
  padding: 0.5rem 1.15rem;
  font-size: 0.88rem;
}

/* Text link with a moving arrow. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  /* These stand alone at the end of a section rather than sitting inside a
     sentence, so they are controls and carry a 44px target. The padding is
     vertical only, so the text still aligns with the copy above it. */
  min-height: 44px;
  padding-block: 0.55rem;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  color: var(--teal-700);
}

/* Inside running copy an arrow-link is an inline link again, and a 44px line
   box there would blow the paragraph's rhythm apart. */
p .arrow-link,
li .arrow-link {
  min-height: 0;
  padding-block: 0;
}

.arrow-link::after {
  content: "→";
  transition: transform 0.18s ease;
}


@media (hover: hover) {
  .arrow-link:hover::after {
    transform: translateX(4px);
  }
}


/* ------------------------------------------------------------- header -- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.site-header.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-sm);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: var(--header-h);
}

/* --- logo lockup --- */
/* The header carries a compact lockup (mark + NATFISH wordmark). The full logo
   including the legal-name lines is only legible at large sizes, so it runs in
   the footer panel and on the About page instead. The artwork is never
   recoloured or filtered. */

.logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
}

.logo img {
  height: 62px;
  width: auto;
  /* Pinned to the approved artwork's own 1789:879. Without this, width:auto
     resolves against whichever srcset derivative happens to be loaded, and
     integer rounding in the 400px tier made the rendered box 2.030:1 instead
     of 2.035:1. Declaring the ratio makes the box exact whatever is served,
     and object-fit keeps the artwork undistorted inside it. */
  aspect-ratio: 1789 / 879;
  object-fit: contain;
}

/* At 2.035:1, 50px tall is a 102px-wide box, which clears the 46px menu button
   with room to spare even at 320px. */
@media (max-width: 1365px) {
  .logo img {
    height: 50px;
  }
}

/* Below 380px the gutters, the language control and the menu button leave the
   logo under 100px, and the organization name stops resolving at all. Trading
   2px of height back keeps the lockup readable without crowding the button. */
@media (max-width: 379px) {
  .logo img {
    height: 46px;
  }
}

/* Full logo on a light panel so the dark footer never forces a recolour. */
.footer-logo-panel {
  display: inline-block;
  padding: 0.9rem 1.15rem;
  margin-bottom: 1.15rem;
  background: var(--white);
  border-radius: var(--radius);
}

.footer-logo-panel img,
.logo-full {
  width: 100%;
  max-width: 300px;
  height: auto;
  aspect-ratio: 1789 / 879;
  object-fit: contain;
}

/* --- primary nav --- */

.nav {
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.4vw, 1.45rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The desktop nav bar carries ten items now that Insights has joined it, and
   the Spanish labels are longer than the English ones. The bar therefore only
   appears from 1366px up; below that the drawer keeps the header, which is
   also where it was already tested. At 1280 in Spanish the row used to push
   the Buyer Enquiry button 29px past the viewport edge and scroll the whole
   page sideways. The nowrap and min-width below stop the list from being the
   thing that grows the header if a label is ever added. */
@media (min-width: 1366px) {
  .nav__list {
    flex-wrap: nowrap;
    min-width: 0;
  }

  /* A flex item will not shrink below its content width unless told it may.
     With ten nav items and the longer Spanish labels, the header row summed to
     one pixel more than the container at 1440 and the whole page picked up a
     1px horizontal scroll. `min-width: 0` lets the row absorb that rounding
     instead of pushing it onto the document. */
  .nav {
    min-width: 0;
  }
}

.nav__link {
  display: inline-block;
  padding: 0.45rem 0.1rem;
  font-size: 0.94rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
  position: relative;
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--teal-600);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.2s ease;
}


@media (hover: hover) {
  .nav__link:hover {
    color: var(--teal-700);
  }
}

@media (hover: hover) {
  .nav__link:hover::after,
  .nav__link[aria-current="page"]::after {
    transform: scaleX(1);
  }
}


.nav__link[aria-current="page"] {
  color: var(--navy-800);
  font-weight: 700;
}

.header-cta {
  flex-shrink: 0;
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-left: auto;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--navy-800);
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 0.22s ease, opacity 0.18s ease;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
}

.nav-toggle__bars::before {
  transform: translateY(-6px);
}

.nav-toggle__bars::after {
  transform: translateY(6px);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  transform: rotate(-45deg);
}

@media (max-width: 1365px) {
  .nav-toggle {
    display: inline-flex;
    position: relative;
  }

  .header-cta {
    display: none;
  }

  /* A compact header on phones. */
  :root {
    --header-h: 76px;
  }

  /* backdrop-filter makes an element the containing block for its fixed
     descendants, so the frosted header was trapping the overlay inside its own
     89px box: the menu opened 64px tall with the hero showing underneath. The
     header is opaque here instead, which puts the fixed .nav back on the
     viewport. Desktop keeps the frosted treatment and has no fixed child. */
  .site-header {
    background: var(--white);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Full-screen overlay menu. It fades in place rather than sliding from
     off-canvas, because an element translated past the right edge is counted
     in the document scroll width and shows up as horizontal overflow. */
  .nav {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    /* Explicit height so the overlay always reaches the bottom of the screen,
       with dvh accounting for mobile browser chrome. */
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    margin: 0;
    background: var(--white);
    padding: 1.25rem var(--gutter) 2.5rem;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
  }

  .nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .nav__list li {
    margin: 0;
  }

  .nav__link {
    display: block;
    padding: 1rem 0;
    font-size: 1.1rem;
    border-bottom: 1px solid var(--line);
  }

  .nav__link::after {
    display: none;
  }

  .nav__cta {
    margin-top: 1.75rem;
  }

  .nav__cta .btn {
    width: 100%;
  }
}

@media (min-width: 1366px) {
  .nav__cta {
    display: none;
  }
}

body.nav-open {
  overflow: hidden;
}

/* --------------------------------------------------------------- hero -- */

/* Split editorial hero. The photographs are the strongest asset in this build,
   so they get their own unobstructed panel instead of being darkened into
   wallpaper behind the headline. No scrim, no text over the image. */
.hero {
  display: grid;
  grid-template-columns: 40% 60%;
  align-items: stretch;
  background: var(--navy-800);
}

.hero > * {
  min-width: 0;
}

.hero__panel {
  display: flex;
  align-items: center;
  background:
    radial-gradient(120% 90% at 8% 4%, rgba(34, 167, 188, 0.22), transparent 62%),
    linear-gradient(168deg, var(--navy-800) 0%, var(--navy-900) 100%);
  padding: clamp(2.75rem, 5vw, 5rem) clamp(1.5rem, 3.2vw, 3.5rem);
}

.hero__content {
  width: 100%;
  max-width: 34rem;
  margin-left: auto;
}

.hero__eyebrow {
  margin-bottom: 1rem;
  font-size: 0.79rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--turq-300);
}

.hero h1 {
  font-size: clamp(1.95rem, 3.3vw, 2.85rem);
  color: var(--white);
  line-height: 1.13;
  letter-spacing: -0.016em;
  margin-bottom: 1.1rem;
}

.hero__copy {
  color: rgba(255, 255, 255, 0.85);
  font-size: clamp(1.02rem, 1.4vw, 1.13rem);
  margin-bottom: 2rem;
  max-width: 36ch;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}

.hero__actions .btn {
  white-space: nowrap;
  padding-block: 0.6rem;
}

/* The image panel: full colour, no overlay. */
.hero__media {
  position: relative;
  overflow: hidden;
  background: var(--navy-900);
  min-height: clamp(420px, 60vh, 660px);
}

.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.9s ease;
}

.hero__slide.is-active {
  opacity: 1;
}

.hero__slide picture,
.hero__slide img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* object-position is set per slide inline, so each photograph keeps its own
   subject in frame rather than sharing one crop. */
.hero__slide img {
  object-fit: cover;
}

/* A thin turquoise seam where the panel meets the photograph. */
.hero__media::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  z-index: 2;
  background: linear-gradient(180deg, var(--turq-500), rgba(34, 167, 188, 0.15));
}

@media (max-width: 900px) {
  /* Stacked: photograph first at full width, then the navy panel. Nothing is
     printed over the image on mobile. */
  .hero {
    grid-template-columns: 1fr;
  }

  .hero__media {
    order: -1;
    min-height: 0;
    /* Raised from a 250px floor. `cover` crops the horizontal axis at these
       ratios, so a taller frame scales the photograph up and the subject grows
       with it: at 390px the fisher goes from about a quarter of the frame to a
       third, which is what "prominently framed" needs on a phone. Checked at
       430, 390 and 360 that the extra side crop still leaves her conch catch,
       the departing boat, and both fishers with the sunrise in shot. */
    height: clamp(300px, 62vw, 380px);
  }

  .hero__media::before {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: auto;
    height: 3px;
    background: linear-gradient(90deg, var(--turq-500), rgba(34, 167, 188, 0.15));
  }

  .hero__content {
    max-width: none;
    margin-left: 0;
  }

  .hero__copy {
    max-width: 34ch;
  }
}

/* Below 600px the hero is served the client's portrait crop instead of the
   landscape one (see hero_picture in tools/build_shell.py). The frame is the
   same 9:16 as that crop, so every slide shows exactly as the client composed
   it - nothing is cropped, and no focal point is needed on any of them.

   This was a roughly square frame first, which showed about 60% of each crop
   through a per-slide window. The client asked twice to see the crops whole:
   the diver's lower half was gone, and the product collage lost its label.
   A frame that matches the crop is the only honest answer to "show it as is".

   The cost is height: at 390px wide the photograph is 693px tall, so on most
   phones the first screen is the photograph and the headline sits just below
   it - the shape of a full-bleed portrait hero. On the smallest screens
   (320x568, 360x640) the photograph itself runs a little past the fold. */
@media (max-width: 600px) {
  .hero__media {
    /* Full width, 9:16 tall, but never taller than the screen.

       `aspect-ratio` cannot express this on its own: pair it with a
       `max-height` and the box honours the ratio by shrinking its WIDTH, so a
       small phone got a narrow strip of photograph with empty bands either
       side. Driving the height directly keeps the photograph full-bleed and
       lets the cap take the height only. 16/9 of the viewport width is the
       9:16 portrait height.

       The frame may never be taller than the screen it is on.

       Without this cap a 9:16 frame is simply width x 1.78, which is right on
       a tall phone and absurd anywhere short: in a 500x380 preview panel the
       photograph came out 889px tall, so all a visitor saw was a band of sky
       with the headline a thousand pixels below the fold. The hero read as
       missing, and it was this rule that did it.

       On the phones this is actually for, the cap never binds - 390x844 allows
       780px against a 693px frame, 430x932 allows 868 against 764 - so the
       client's crops still show whole. It binds only on short windows and on
       the two smallest legacy phones (320x568, 360x640), where the frame is
       clamped to the screen and `cover` trims about a tenth off the height.
       A tenth trimmed beats a photograph three screens tall. */
    height: min(calc(100vw * 16 / 9), calc(100vh - 4rem));
    height: min(calc(100vw * 16 / 9), calc(100dvh - 4rem));
  }
}

@media (max-width: 480px) {
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ------------------------------------------------- identity ribbon -- */
/* The registered name as a registry line, not hero copy. */

.identity-ribbon {
  background: var(--navy-900);
  border-top: 1px solid rgba(34, 167, 188, 0.35);
  border-bottom: 1px solid rgba(217, 80, 58, 0.4);
}

.identity-ribbon__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.3rem 1.75rem;
  padding-block: 0.85rem;
}

.identity-ribbon__name {
  margin: 0;
  font-size: clamp(0.82rem, 1.35vw, 0.97rem);
  font-weight: 600;
  letter-spacing: 0.055em;
  color: var(--white);
}

.identity-ribbon__meta {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--turq-300);
}

.identity-ribbon__sep {
  width: 22px;
  height: 1px;
  background: var(--coral);
  opacity: 0.85;
}

@media (max-width: 620px) {
  .identity-ribbon__inner {
    justify-content: flex-start;
  }

  .identity-ribbon__name {
    letter-spacing: 0.03em;
  }
}

/* Page hero used on inner pages. */
.page-hero {
  position: relative;
  padding-block: clamp(3.5rem, 9vw, 6rem);
  background:
    radial-gradient(110% 130% at 88% 0%, rgba(34, 167, 188, 0.3), transparent 60%),
    linear-gradient(155deg, var(--navy-800) 0%, var(--navy-900) 100%);
  color: var(--ink-onDark);
  overflow: hidden;
}

.page-hero h1 {
  color: var(--white);
  max-width: 18ch;
}

.page-hero .lede {
  color: rgba(255, 255, 255, 0.84);
}

.breadcrumb {
  margin-bottom: 1.1rem;
  font-size: 0.83rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--turq-300);
}

.breadcrumb a {
  color: inherit;
  text-decoration: none;
}


@media (hover: hover) {
  .breadcrumb a:hover {
    color: var(--white);
    text-decoration: underline;
  }
}


.breadcrumb span {
  opacity: 0.5;
  margin-inline: 0.45rem;
}

/* --------------------------------------------------------- trust strip -- */

.trust {
  background: var(--navy-800);
  color: var(--white);
}

.trust__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.75rem clamp(1.5rem, 5vw, 4.5rem);
  list-style: none;
  margin: 0;
  padding-block: 1.15rem;
}

.trust__item {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.075em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.9);
}

.trust__item svg {
  width: 17px;
  height: 17px;
  color: var(--turq-300);
  flex-shrink: 0;
}

/* -------------------------------------------------------------- grids -- */

.grid {
  display: grid;
  gap: clamp(1.25rem, 2.6vw, 2rem);
}

.grid > * {
  min-width: 0;
}

.grid--3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid--2 {
  grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 900px) {
  .grid--3 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .grid--3,
  .grid--2 {
    grid-template-columns: 1fr;
  }
}

/* -------------------------------------------------------------- cards -- */

.card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform 0.24s ease, box-shadow 0.24s ease,
    border-color 0.24s ease;
}


@media (hover: hover) {
  .card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md);
    border-color: rgba(14, 124, 139, 0.34);
  }
}


.card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--sand-200);
  overflow: hidden;
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}


@media (hover: hover) {
  .card:hover .card__media img {
    transform: scale(1.045);
  }
}


.card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: clamp(1.35rem, 2.4vw, 1.75rem);
}

.card__body h3 {
  margin-bottom: 0.55rem;
}

.card__body p {
  color: var(--ink-soft);
  font-size: 0.975rem;
  /* Keeps cards from becoming excessively tall on mobile. */
  margin-bottom: 1.15rem;
}

.card__body .arrow-link {
  margin-top: auto;
}

/* Icon-led block used on navy bands. */
.pillar {
  padding: clamp(1.5rem, 2.6vw, 2rem);
  background: rgba(255, 255, 255, 0.055);
  border: 1px solid var(--line-onDark);
  border-radius: var(--radius-lg);
}

.pillar__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: 1.15rem;
  border-radius: var(--radius);
  background: rgba(34, 167, 188, 0.18);
  color: var(--turq-300);
}

.pillar__icon svg {
  width: 26px;
  height: 26px;
}

.pillar p {
  font-size: 0.975rem;
  color: var(--ink-onDark);
}

/* --------------------------------------------------------------- flow -- */
/* FISHERS -> COOPERATIVE -> PROCESSING -> MARKET */

.flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: stretch;
  gap: 0.6rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  list-style: none;
  padding: 0;
}

.flow__step {
  position: relative;
  margin: 0;
  padding: clamp(1.2rem, 2.2vw, 1.6rem) 1rem;
  text-align: center;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.flow__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -0.6rem;
  width: 0.6rem;
  height: 2px;
  background: var(--turq-500);
  transform: translateY(-50%);
  z-index: 1;
}

.flow__num {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--turq-500);
  margin-bottom: 0.5rem;
}

.flow__label {
  display: block;
  font-family: var(--font-body);
  font-size: clamp(0.86rem, 1.5vw, 1rem);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--navy-800);
  line-height: 1.25;
}

.flow__note {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.83rem;
  color: var(--ink-soft);
  line-height: 1.45;
}

@media (max-width: 760px) {
  .flow {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }

  .flow__step:not(:last-child)::after {
    top: auto;
    right: auto;
    left: 50%;
    bottom: -1.05rem;
    width: 2px;
    height: 0.9rem;
    transform: translateX(-50%);
  }
}

/* -------------------------------------------------------------- split -- */

.split {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: center;
  gap: clamp(1.75rem, 5vw, 4rem);
}

.split > * {
  min-width: 0;
}

.split--media-right .split__media {
  order: 2;
}

.split__media {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  background: var(--sand-200);
}

.split__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.split__media--tall img {
  aspect-ratio: 3 / 4;
}

@media (max-width: 860px) {
  .split {
    grid-template-columns: 1fr;
  }

  .split--media-right .split__media {
    order: 0;
  }

  .split__media img,
  .split__media--tall img {
    aspect-ratio: 16 / 10;
  }
}

/* ------------------------------------------------------------- stats  -- */

.factlist {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  list-style: none;
  padding: 0;
  margin: 0;
}

.factlist li {
  margin: 0;
  padding: 1.05rem 1.25rem;
  background: var(--white);
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.95rem;
}

.factlist dt,
.factlist .factlist__key {
  font-weight: 650;
  color: var(--navy-800);
}

.factlist .factlist__val {
  color: var(--ink-soft);
  text-align: right;
}


/* --------------------------------------------------- opening hours ----- */
/* Two schedules on the Visit card, each a small definition list so the day
   range and the time stay paired when the card narrows. */

.hours {
  margin: 0 0 0.9rem;
}

.hours__label {
  margin: 0 0 0.3rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--teal-600);
}

.hours__list {
  margin: 0;
  display: grid;
  gap: 0.2rem;
}

.hours__list > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.6rem;
  justify-content: space-between;
}

.hours__list dt {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink);
}

.hours__list dd {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------- inline figure ----- */
/* A photograph that belongs to a paragraph rather than to the section. It sits
   in the copy column at a modest width so a tall portrait file cannot outgrow
   the text it illustrates, which is what happened when this one was stacked
   into the media column instead. */

.inline-figure {
  margin: 1.35rem 0 0;
  max-width: 300px;
}

.inline-figure img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}

@media (max-width: 620px) {
  .inline-figure { max-width: 240px; }
}

/* ------------------------------------------------- NATFISH in Motion ---- */
/* Three YouTube Shorts. Shorts are 9:16, so the frame is 9:16 and the player
   is never cropped or letterboxed.

   The column width is capped rather than left to fill the container: three
   9:16 cards across a 1200px container would each be 380px wide and 676px
   tall, a band taller than most laptop screens. At 320px they are 569px tall,
   which reads as a row of phone-shaped clips rather than a wall.

   `place-content: center` matters at the two- and one-column steps, where the
   capped tracks no longer fill the row. */

.video-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 320px));
  justify-content: center;
  gap: clamp(1rem, 2.4vw, 1.75rem);
}

.video-grid > * {
  min-width: 0;
}

.video-card {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  margin: 0;
}

.video-card__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--navy-900);
  box-shadow: var(--shadow-lg);
}

/* One rule for both kinds of player: the YouTube iframe and the self-hosted
   file fill the same 9:16 frame. `object-fit: contain` on the video, not
   cover: the file is 478x850, exactly the frame's ratio, and contain means a
   future clip of a different shape is letterboxed rather than cropped. */
.video-card__frame iframe,
.video-card__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.video-card__frame video {
  object-fit: contain;
  background: var(--navy-900);
}

/* Only the shareable single-file preview uses this: the artifact CSP blocks
   the player, so the frame carries a link out instead of an empty box. */
.video-card__stub {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: clamp(1rem, 4vw, 1.6rem);
  text-align: center;
  text-decoration: none;
  color: var(--white);
}

.video-card__stub-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.video-card__stub-note {
  font-size: 0.82rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.78);
}

.video-card__title {
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1.35;
  color: var(--ink);
  text-align: center;
}

@media (max-width: 900px) {
  .video-grid { grid-template-columns: repeat(2, minmax(0, 320px)); }
}

@media (max-width: 560px) {
  .video-grid { grid-template-columns: minmax(0, 340px); }
}

/* -------------------------------------------------------------- video -- */

.video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--navy-900);
  box-shadow: var(--shadow-lg);
}

.video__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--white);
}

.video__poster img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video__poster::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(3, 25, 42, 0.36) 0%,
    rgba(3, 25, 42, 0.58) 100%
  );
}

.video__play {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(64px, 9vw, 84px);
  height: clamp(64px, 9vw, 84px);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  color: var(--teal-700);
  box-shadow: 0 10px 40px rgba(3, 25, 42, 0.35);
  transition: transform 0.22s ease, background-color 0.22s ease;
}

.video__play svg {
  width: 26px;
  height: 26px;
  margin-left: 4px;
}


@media (hover: hover) {
  .video__poster:hover .video__play {
    transform: scale(1.07);
    background: var(--white);
  }
}


.video__label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  padding: 1.5rem clamp(1.15rem, 3vw, 2rem);
  text-align: left;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--white);
  text-shadow: 0 1px 10px rgba(3, 25, 42, 0.5);
}

.video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.video-credit {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.section--navy .video-credit {
  color: rgba(255, 255, 255, 0.62);
}

/* -------------------------------------------------------------- forms -- */

.form-panel {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3.2vw, 2.5rem);
  box-shadow: var(--shadow-md);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
}

.form-grid > * {
  min-width: 0;
}

.field--full {
  grid-column: 1 / -1;
}

@media (max-width: 620px) {
  .form-grid {
    grid-template-columns: 1fr;
  }
}

.field label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
  font-weight: 650;
  letter-spacing: 0.03em;
  color: var(--navy-800);
}

.field .opt {
  font-weight: 500;
  color: var(--ink-soft);
  letter-spacing: 0;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 50px;
  padding: 0.75rem 0.9rem;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--sand);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 0.18s ease, background-color 0.18s ease,
    box-shadow 0.18s ease;
}

.field textarea {
  min-height: 130px;
  resize: vertical;
}

.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%234a6376' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
  background-size: 12px;
  padding-right: 2.4rem;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  background: var(--white);
  border-color: var(--teal-600);
  box-shadow: 0 0 0 3px rgba(14, 124, 139, 0.16);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--turq-500);
  outline-offset: 1px;
}

.field .error {
  display: none;
  margin-top: 0.35rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--coral);
}

.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--coral);
  background: rgba(217, 80, 58, 0.04);
}

.field.is-invalid .error {
  display: block;
}

.form-foot {
  margin-top: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
}

.form-foot .note {
  flex: 1 1 240px;
}

/* Success panel shown in place of the form. */
.form-success {
  display: none;
  text-align: center;
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1rem, 3vw, 2rem);
}

.form-success.is-visible {
  display: block;
}

.form-success__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  margin-bottom: 1.15rem;
  border-radius: 50%;
  background: rgba(14, 124, 139, 0.12);
  color: var(--teal-600);
}

.form-success__icon svg {
  width: 30px;
  height: 30px;
}

.form-success__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.btn--whatsapp {
  background: #1ea952;
  border-color: #1ea952;
  color: var(--white);
}


@media (hover: hover) {
  .btn--whatsapp:hover {
    background: #16853f;
    border-color: #16853f;
    color: var(--white);
  }
}


.btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.form-success__restart {
  margin-top: 1.25rem;
  font-size: 0.88rem;
}

.form-success__restart button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: inherit;
  color: var(--teal-700);
  text-decoration: underline;
  cursor: pointer;
}

/* --------------------------------------------------------------- news -- */

.news-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: clamp(1.4rem, 2.4vw, 1.85rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--turq-500);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}


@media (hover: hover) {
  .news-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
  }
}


.news-card__tag {
  display: inline-block;
  align-self: flex-start;
  margin-bottom: 0.9rem;
  padding: 0.28rem 0.7rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--teal-700);
  background: rgba(14, 124, 139, 0.1);
  border-radius: 999px;
}

.news-card h3 {
  font-size: 1.12rem;
  margin-bottom: 0.6rem;
}

.news-card p {
  font-size: 0.95rem;
  color: var(--ink-soft);
  margin-bottom: 1.2rem;
}

.news-card__source {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.news-card__source a {
  font-weight: 600;
}

/* ------------------------------------------------------------ gallery -- */

.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(0.6rem, 1.2vw, 1rem);
}

.gallery > * {
  min-width: 0;
}

.gallery__item {
  position: relative;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--sand-200);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: zoom-in;
  aspect-ratio: 4 / 3;
}

.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.45s ease, filter 0.3s ease;
}

.gallery__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(3, 25, 42, 0.45));
  opacity: 0;
  transition: opacity 0.3s ease;
}


@media (hover: hover) {
  .gallery__item:hover img {
    transform: scale(1.05);
  }
}

@media (hover: hover) {
  .gallery__item:hover::after {
    opacity: 1;
  }
}


.gallery__item--wide {
  grid-column: span 2;
}

.gallery__item--tall {
  grid-row: span 2;
  aspect-ratio: auto;
}

@media (max-width: 860px) {
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  .gallery__item--tall {
    grid-row: span 1;
    aspect-ratio: 4 / 3;
  }
}

@media (max-width: 460px) {
  .gallery {
    grid-template-columns: 1fr;
  }

  .gallery__item--wide {
    grid-column: span 1;
  }
}

/* --- lightbox --- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(3, 25, 42, 0.94);
}

.lightbox.is-open {
  display: flex;
}

.lightbox img {
  max-width: 100%;
  max-height: 82vh;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

.lightbox__caption {
  margin-top: 1rem;
  text-align: center;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.78);
  max-width: 60ch;
}

.lightbox__figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lightbox__btn {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--white);
  cursor: pointer;
  transition: background-color 0.18s ease;
}


@media (hover: hover) {
  .lightbox__btn:hover {
    background: rgba(255, 255, 255, 0.2);
  }
}


.lightbox__btn svg {
  width: 20px;
  height: 20px;
}

.lightbox__close {
  top: clamp(0.75rem, 2.5vw, 1.5rem);
  right: clamp(0.75rem, 2.5vw, 1.5rem);
}

.lightbox__prev {
  left: clamp(0.5rem, 2vw, 1.5rem);
  top: 50%;
  transform: translateY(-50%);
}

.lightbox__next {
  right: clamp(0.5rem, 2vw, 1.5rem);
  top: 50%;
  transform: translateY(-50%);
}

/* ------------------------------------------------------------ contact -- */

.contact-band {
  position: relative;
  background: var(--navy-900);
  color: var(--ink-onDark);
  overflow: hidden;
}

.contact-band__media {
  position: absolute;
  inset: 0;
}

.contact-band__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.contact-band__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(3, 25, 42, 0.95) 0%,
    rgba(3, 25, 42, 0.8) 48%,
    rgba(3, 25, 42, 0.5) 100%
  );
}

.contact-band .container {
  position: relative;
  z-index: 1;
}

.contact-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1.75rem;
}

.contact-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  margin-bottom: 1.1rem;
}

.contact-list svg {
  width: 20px;
  height: 20px;
  margin-top: 0.22rem;
  color: var(--turq-300);
  flex-shrink: 0;
}

.contact-list a {
  color: var(--white);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(127, 215, 228, 0.5);
}


@media (hover: hover) {
  .contact-list a:hover {
    color: var(--turq-300);
    border-bottom-color: var(--turq-300);
  }
}


.contact-list__label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 0.15rem;
  font-weight: 600;
}

/* ------------------------------------------------------------- footer -- */

.site-footer {
  background: var(--navy-900);
  color: rgba(255, 255, 255, 0.68);
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
  font-size: 0.94rem;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1.2fr;
  gap: clamp(2rem, 5vw, 4rem);
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line-onDark);
}

.footer-grid > * {
  min-width: 0;
}

@media (max-width: 800px) {
  .footer-grid {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }
}

.site-footer h4 {
  font-size: 0.78rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--turq-300);
  margin-bottom: 1.1rem;
}

.site-footer .logo {
  margin-bottom: 1.1rem;
}

.footer-about p {
  max-width: 42ch;
  font-size: 0.92rem;
  line-height: 1.6;
}

.footer-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.footer-list li {
  margin-bottom: 0.6rem;
}

.footer-list a {
  color: rgba(255, 255, 255, 0.72);
  text-decoration: none;
}


@media (hover: hover) {
  .footer-list a:hover {
    color: var(--white);
    text-decoration: underline;
  }
}


.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.75rem;
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.5);
}

.footer-bottom p {
  margin: 0;
}

/* ----------------------------------------------------------- reveal  -- */

/* The reveal rises on `translate`, not `transform`, and that is deliberate.

   `.reveal.is-visible { transform: none }` sits later in this file than the
   component hover rules and ties with them on specificity, so it won on source
   order and quietly cancelled every hover lift on a revealed element - the
   seafood cards, the news cards, the product rows. They had never lifted.

   `translate` is an independent transform property: it composes with
   `transform` instead of replacing it, so the reveal and the hover no longer
   fight over the same declaration. Keep them on separate properties. */
.reveal {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 0.65s ease, translate 0.65s ease;
}

.reveal.is-visible {
  opacity: 1;
  translate: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }

  .reveal {
    opacity: 1;
    translate: none;
  }

  @media (hover: hover) {
    .btn:hover,
    .card:hover,
    .news-card:hover {
      transform: none;
    }
  }

}

/* Without JS the reveal elements must still be visible. */
.no-js .reveal {
  opacity: 1;
  translate: none;
}

/* ==========================================================================
   Seven-page restructure: carousel and page components
   ========================================================================== */

/* ----------------------------------------------------- hero carousel -- */
/* Slides stack in the same box and cross-fade, so nothing reflows as the
   carousel advances. The existing .hero__media rules already position and crop
   the images; only the stacking and fade are added here. */

.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.9s ease;
}

.hero__slide.is-active {
  opacity: 1;
}

.hero--carousel .hero__inner {
  z-index: 2;
}

/* ------------------------------------------------------ section heads -- */

.section-head--split {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
  max-width: none;
}

.section-head--split h2 {
  margin-bottom: 0;
}

/* ------------------------------------------------------------ notices -- */

.notice {
  padding: 1.05rem 1.25rem;
  margin: 0;
  background: var(--sand);
  border: 1px solid var(--line);
  border-left: 3px solid var(--turq-500);
  border-radius: var(--radius);
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.section--sand .notice {
  background: var(--white);
}

/* ----------------------------------------------------- identity panel -- */

.identity-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

.identity-panel > * {
  min-width: 0;
}

.identity-panel .logo-full {
  max-width: 380px;
  flex: 1 1 260px;
}

.identity-panel > div {
  flex: 1 1 300px;
}

/* --------------------------------------------------------- timeline  -- */

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.timeline li {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 0 clamp(1rem, 2.5vw, 2rem);
  padding-bottom: 2rem;
  margin: 0;
  border-left: 2px solid var(--line);
  padding-left: clamp(1rem, 3vw, 1.75rem);
}

.timeline li:last-child {
  padding-bottom: 0;
  border-left-color: transparent;
}

.timeline__year {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal-600);
  padding-top: 0.3rem;
}

.timeline h3 {
  margin-bottom: 0.4rem;
}

.timeline p {
  color: var(--ink-soft);
  font-size: 0.975rem;
}

@media (max-width: 620px) {
  .timeline li {
    grid-template-columns: 1fr;
    gap: 0.35rem;
  }
}

/* ------------------------------------------------------ update cards -- */

.update-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}


@media (hover: hover) {
  .update-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
  }
}


.update-card__media {
  aspect-ratio: 16 / 9;
  background: var(--sand-200);
  overflow: hidden;
}

.update-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.update-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: clamp(1.3rem, 2.4vw, 1.75rem);
}

.update-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.85rem;
}

.update-card__tag {
  padding: 0.28rem 0.7rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--teal-700);
  background: rgba(14, 124, 139, 0.1);
  border-radius: 999px;
}

.update-card__date {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.update-card h3 {
  font-size: 1.12rem;
  margin-bottom: 0.55rem;
}

.update-card p {
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.update-card__source {
  margin-top: auto;
  padding-top: 1rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.update-card__source a {
  font-weight: 600;
}

/* Featured update: media beside body on desktop. */
.feature-update {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  align-items: stretch;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.feature-update > * {
  min-width: 0;
}

.feature-update__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 4 / 3;
}

.feature-update__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(1.6rem, 3.5vw, 3rem);
}

@media (max-width: 860px) {
  .feature-update {
    grid-template-columns: 1fr;
  }

  .feature-update__media img {
    aspect-ratio: 16 / 9;
  }
}

/* ------------------------------------------------------- gallery page -- */

.gallery {
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
}

.gallery__figure {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0;
  min-width: 0;
}

.gallery__figure--wide {
  grid-column: span 2;
}

.gallery__figure figcaption {
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.gallery__figure .gallery__item {
  width: 100%;
}

@media (max-width: 860px) {
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 460px) {
  .gallery {
    grid-template-columns: 1fr;
  }

  .gallery__figure--wide {
    grid-column: span 1;
  }
}

/* ------------------------------------------- gallery filter tabs ------ */
/* Unobtrusive by instruction: a label and a row of quiet pills, not a second
   navigation. It sits between the section heading and the grid, centred to
   match the heading above it. */

.gallery-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.85rem;
  margin-block: 0 clamp(1.1rem, 2.4vw, 1.75rem);
}

.gallery-filter__label {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.gallery-filter__tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
}

.gallery-filter__btn {
  /* 44px tall so a thumb can hit it, which a small pill would otherwise fail. */
  min-height: 44px;
  padding: 0.4rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  font-size: 0.86rem;
  line-height: 1.2;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}


@media (hover: hover) {
  .gallery-filter__btn:hover {
    border-color: var(--teal-600);
    color: var(--teal-600);
  }
}


.gallery-filter__btn.is-active {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--white);
}

/* On sand the white pill would float; on navy neither token reads. Only the
   sand case exists today, and it is one line rather than a second palette. */
.section--sand .gallery-filter__btn {
  background: transparent;
}

.section--sand .gallery-filter__btn.is-active {
  background: var(--navy-900);
}

/* The gallery is a CSS columns layout, so `.gallery__figure` carries an author
   `display`. A UA-level [hidden] rule loses to it, and a filtered-out figure
   would stay on screen. This is the same trap that once left the closed
   NATFISH AI panel swallowing taps; it is spelled out both places on purpose. */
.gallery__figure[hidden] {
  display: none;
}

.gallery-empty {
  margin: 0;
  text-align: center;
  color: var(--ink-soft);
}

/* Homepage gallery teaser: four crops that link through. */
.gallery-preview {
  display: grid;
  /* Three tiles, not four: the homepage has fourteen photographs to place and
     a four-up teaser could only fill itself by repeating one from the sections
     above. Three keeps every tile new. */
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.5rem, 1.2vw, 0.9rem);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
}

.gallery-preview > * {
  min-width: 0;
}

.gallery-preview img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  transition: transform 0.4s ease, filter 0.3s ease;
}


@media (hover: hover) {
  .gallery-preview:hover img {
    filter: brightness(1.06);
  }
}


@media (max-width: 700px) {
  .gallery-preview {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* --------------------------------------------------------- cta bands -- */

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.btn--onDark {
  border-color: var(--line-onDark);
  color: var(--white);
}


@media (hover: hover) {
  .btn--onDark:hover {
    border-color: var(--turq-300);
    color: var(--turq-300);
    background: rgba(255, 255, 255, 0.06);
  }
}


/* ------------------------------------------------------ contact strip -- */

.contact-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

.contact-strip > * {
  min-width: 0;
}

.contact-strip__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.contact-strip__list li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  font-size: 0.95rem;
}

.contact-strip__list svg {
  width: 18px;
  height: 18px;
  color: var(--teal-600);
  flex-shrink: 0;
}

.contact-strip__list a {
  text-decoration: none;
  font-weight: 600;
}


@media (hover: hover) {
  .contact-strip__list a:hover {
    text-decoration: underline;
  }
}


/* ----------------------------------------------------- enquiry blocks -- */

.enquiry {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: start;
}

.enquiry > * {
  min-width: 0;
}

@media (max-width: 860px) {
  .enquiry {
    grid-template-columns: 1fr;
  }
}

.enquiry__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin: 1.75rem 0 0.9rem;
}

.enquiry__actions .btn {
  flex: 1 1 230px;
}

.btn--whatsapp {
  background: #1ea952;
  border-color: #1ea952;
  color: var(--white);
}


@media (hover: hover) {
  .btn--whatsapp:hover {
    background: #16853f;
    border-color: #16853f;
    color: var(--white);
  }
}


.btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.enquiry__checklist {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

.enquiry__checklist h3 {
  font-size: 1.05rem;
  margin-bottom: 1.1rem;
}

.checklist {
  list-style: none;
  margin: 0;
  padding: 0;
}

.checklist li {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  margin-bottom: 0.75rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.checklist li:last-child {
  margin-bottom: 0;
}

.checklist svg {
  width: 16px;
  height: 16px;
  margin-top: 0.28rem;
  color: var(--teal-600);
  flex-shrink: 0;
}

/* -------------------------------------------------------- contact card -- */

.contact-card {
  padding: clamp(1.4rem, 2.6vw, 1.9rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.contact-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: 1rem;
  border-radius: var(--radius-sm);
  background: rgba(14, 124, 139, 0.1);
  color: var(--teal-600);
}

.contact-card__icon svg {
  width: 22px;
  height: 22px;
}

.contact-card h3 {
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}

.contact-card p {
  color: var(--ink-soft);
  font-size: 0.975rem;
  margin-bottom: 0.9rem;
}

/* ----------------------------------------------------- reduced motion -- */

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

  @media (hover: hover) {
    .update-card:hover,
    .gallery-preview:hover img {
      transform: none;
    }
  }
}

/* ==========================================================================
   Icon system and editorial de-templating
   ========================================================================== */

/* One family: 24px viewBox, 1.85 stroke, navy from currentColor, turquoise on
   accented paths, coral kept for the rare highlight. */
.ico {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.ico__accent {
  stroke: var(--turq-500);
}

.ico__coral {
  stroke: var(--coral);
}

/* On navy the accent needs to lift off the ground. */
.section--navy .ico__accent,
.identity-ribbon .ico__accent,
.contact-band .ico__accent,
.site-footer .ico__accent {
  stroke: var(--turq-300);
}

/* Feature icons sit on an open baseline rule rather than in yet another
   rounded square. The repeated icon-in-a-tile is the single most template-like
   pattern in the previous build. */
.pillar__icon {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  width: auto;
  height: auto;
  margin-bottom: 1rem;
  padding-bottom: 0.85rem;
  border-radius: 0;
  background: none;
  border-bottom: 2px solid rgba(34, 167, 188, 0.5);
  color: var(--turq-300);
}

.pillar__icon .ico {
  width: 30px;
  height: 30px;
}

.contact-card__icon {
  display: inline-flex;
  width: auto;
  height: auto;
  margin-bottom: 0.9rem;
  padding-bottom: 0.75rem;
  border-radius: 0;
  background: none;
  border-bottom: 2px solid rgba(14, 124, 139, 0.35);
  color: var(--teal-600);
}

.contact-card__icon .ico {
  width: 26px;
  height: 26px;
}

/* A species mark set beside its own heading. */
.h-icon {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
}

.h-icon .h-icon__mark {
  margin-top: 0.12em;
}

.h-icon__mark {
  width: 30px;
  height: 30px;
  color: var(--teal-600);
  flex-shrink: 0;
}

/* Icons in running lists inherit the text colour and sit on the first line. */
.contact-list .ico,
.contact-strip__list .ico,
.trust__item .ico,
.checklist .ico {
  width: 19px;
  height: 19px;
}

.checklist .ico {
  margin-top: 0.2rem;
  color: var(--teal-600);
}

.btn .ico {
  width: 18px;
  height: 18px;
}

/* --------------------------------------------------- editorial rhythm -- */

/* The rope-and-wave rule that used to sit above section headings is gone at
   the client's request, along with the eyebrow dash and the hairline. Its
   markup is gone too - RULE_WAVE in tools/build_shell.py no longer emits an
   SVG - so there is nothing left to style. */

/* Editorial heads. The 2px hairline that ran above these is gone with the rest
   of the heading ornament; the class is kept because it is on every section
   head in the markup and still carries the head's own top spacing. */
.section-head--rule {
  padding-top: 0.4rem;
}

.section-head--rule .eyebrow {
  margin-bottom: 0.7rem;
}

/* Bitter carries the numerals in the timeline and the flow, which is where the
   display face earns its keep. */
.timeline__year,
.flow__num {
  font-family: var(--font-display);
  font-weight: 700;
}

.timeline__year {
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* Pull quote / significant date, set in the display face. */
.stat-line {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.6vw, 1.9rem);
  line-height: 1.25;
  color: var(--navy-800);
  letter-spacing: -0.012em;
}

.section--navy .stat-line {
  color: var(--white);
}

/* ==========================================================================
   Bilingual control, branding and alignment corrections
   ========================================================================== */

/* ------------------------------------------------------ language toggle -- */

.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  /* 44px minimum: this is a primary control on every page, and at 34px it was
     the smallest tap target on the site. */
  min-height: 44px;
  padding: 0.42rem 0.75rem;
  border: 1.5px solid var(--line);
  border-radius: 7px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--navy-800);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.18s ease, color 0.18s ease, background-color 0.18s ease;
}


@media (hover: hover) {
  .lang-toggle:hover {
    border-color: var(--teal-600);
    color: var(--teal-700);
    background: rgba(14, 124, 139, 0.05);
  }
}


.lang-toggle__globe {
  display: inline-flex;
  color: var(--teal-600);
}

.lang-toggle__globe svg {
  width: 17px;
  height: 17px;
}

/* On mobile it sits between the compact logo and the hamburger. */
@media (max-width: 1365px) {
  .lang-toggle {
    margin-left: auto;
    margin-right: 0.6rem;
  }
}

@media (max-width: 400px) {
  .lang-toggle {
    padding-inline: 0.55rem;
  }

  .lang-toggle__label {
    font-size: 0.8rem;
  }
}

/* Above the drawer breakpoint the toggle sits after the nav, before the CTA. */
@media (min-width: 1366px) {
  .lang-toggle {
    margin-left: 0.9rem;
    margin-right: 0.15rem;
  }
}

/* --------------------------------------------------------- brand weight -- */

/* The registered name is the point of the ribbon, so it carries more weight. */
.identity-ribbon__name {
  font-size: clamp(0.9rem, 1.5vw, 1.09rem);
  font-weight: 700;
  letter-spacing: 0.045em;
}

.hero__eyebrow strong {
  color: var(--white);
  font-weight: 700;
  letter-spacing: 0.16em;
}

.hero__eyebrow-sep {
  opacity: 0.5;
  margin-inline: 0.15rem;
}

/* Oversized NATFISH behind inner-page headings. Understated: it sits under the
   content, clipped by the band, and never competes with the h1. */
.page-hero {
  position: relative;
  isolation: isolate;
}

/* The watermark is decorative and sits a fraction outside the hero on purpose,
   so the letter's side bearing lines up with the edge rather than its glyph
   box. That nudge is 12px at the largest size, and without a clip it grew the
   document and gave the page a 1px horizontal scroll - in Spanish, where the
   heading above it is longer, it was the only thing over the line. The hero
   clips instead, so the optical adjustment stays and the overflow does not.
   `hidden`, not `clip`. `clip` stops the painting but Chromium still counted
   the clipped box in the root's scrollWidth, which left a 1px horizontal
   scroll behind - measured, not assumed. `hidden` establishes a scroll
   container and ends it. Nothing in this hero is sticky, so there is nothing
   to lose by it. */
.page-hero {
  overflow: hidden;
}

.page-hero__watermark {
  position: absolute;
  right: -0.06em;
  bottom: -0.3em;
  z-index: -1;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(5rem, 17vw, 13rem);
  line-height: 0.8;
  letter-spacing: -0.03em;
  color: rgba(255, 255, 255, 0.05);
  pointer-events: none;
  user-select: none;
}

@media (max-width: 700px) {
  .page-hero__watermark {
    font-size: clamp(4rem, 26vw, 8rem);
    color: rgba(255, 255, 255, 0.045);
  }
}

/* ------------------------------------------------------ site credit -- */

.site-credit {
  margin: 1.75rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-onDark);
  text-align: center;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.62);
}

.site-credit a {
  color: rgba(255, 255, 255, 0.9);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
  transition: color 0.18s ease, border-color 0.18s ease;
}


@media (hover: hover) {
  .site-credit a:hover {
    color: var(--turq-300);
    border-bottom-color: var(--turq-300);
  }
}


/* ------------------------------------------- alignment corrections -- */

/* Headings that introduce a card grid are centred, with their lede centred
   too. Long editorial copy stays left-aligned for readability. */
.section-head--center .lede {
  margin-inline: auto;
}

/* Card-based icon groups centre as a unit. */
.pillar--center,
.contact-card {
  text-align: center;
}

.pillar--center .pillar__icon,
.contact-card__icon {
  justify-content: center;
  align-self: center;
  margin-inline: auto;
  padding-inline: 1.5rem;
}

.contact-card .arrow-link {
  justify-content: center;
}

/* The homepage contact strip centres on mobile, where it stacks. */
@media (max-width: 820px) {
  .contact-strip {
    text-align: center;
    justify-content: center;
  }

  .contact-strip__list {
    justify-content: center;
  }

  .contact-strip__list li {
    justify-content: center;
  }

  .contact-strip .btn {
    width: 100%;
  }
}

/* ==========================================================================
   Seafood Seasons
   ========================================================================== */

/* Inner-page split hero, same composition as the homepage. */
.hero--page .hero__media {
  min-height: clamp(360px, 46vh, 540px);
}

.hero--page .breadcrumb {
  margin-bottom: 1.1rem;
}

.notice--strong {
  background: rgba(217, 80, 58, 0.06);
  border-left-color: var(--coral);
  color: var(--ink);
}

.season-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(1.15rem, 2.2vw, 1.6rem);
  align-items: stretch;
}

.season-grid > * {
  min-width: 0;
}

.season-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: clamp(1.35rem, 2.4vw, 1.85rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--teal-600);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.season-card__head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1rem;
}

.season-card__icon {
  display: inline-flex;
  color: var(--teal-600);
}

.season-card__icon .ico {
  width: 30px;
  height: 30px;
}

.season-card__head h3 {
  margin: 0;
  font-size: 1.12rem;
}

/* Status wording is drawn from a fixed permitted set: it describes the
   regulatory period only, never stock. */
.season-status {
  margin: 0 0 1.1rem;
  padding: 0.5rem 0.8rem;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.4;
  background: var(--sand);
  color: var(--ink-soft);
}

.season-status--open {
  background: rgba(14, 124, 139, 0.1);
  color: var(--teal-700);
}

.season-status--closed {
  background: rgba(217, 80, 58, 0.09);
  color: #a8381f;
}

.season-facts {
  margin: 0 0 0.9rem;
  display: grid;
  gap: 0.55rem;
}

.season-facts div {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.3rem 1rem;
  align-items: baseline;
  padding-bottom: 0.55rem;
  border-bottom: 1px solid var(--line);
}

.season-facts div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.season-facts dt {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.season-facts dd {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: right;
  color: var(--navy-800);
}

@media (max-width: 400px) {
  .season-facts div {
    grid-template-columns: 1fr;
  }

  .season-facts dd {
    text-align: left;
  }
}

.season-card__note,

.season-card__note {
  padding-top: 0.85rem;
  border-top: 1px solid var(--line);
}

.season-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: 1.25rem;
  border-top: 2px solid var(--navy-800);
  font-size: 0.88rem;
}

.season-meta p {
  margin: 0;
}

.season-meta__label {
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.season-meta__value {
  font-weight: 650;
  color: var(--navy-800);
  margin-left: 0.4rem;
}

/* ------------------------------------------ homepage seasons feature -- */

.season-feature {
  display: grid;
  grid-template-columns: 52% 48%;
  align-items: stretch;
  background: var(--navy-800);
}

.season-feature > * {
  min-width: 0;
}

.season-feature__media {
  position: relative;
  overflow: hidden;
  min-height: clamp(320px, 42vh, 520px);
}

.season-feature__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.season-feature__panel {
  display: flex;
  align-items: center;
  padding: clamp(2.5rem, 4.5vw, 4.5rem) clamp(1.5rem, 3vw, 3.5rem);
  background:
    radial-gradient(120% 90% at 92% 6%, rgba(34, 167, 188, 0.22), transparent 62%),
    linear-gradient(196deg, var(--navy-800) 0%, var(--navy-900) 100%);
}

.season-feature__inner {
  max-width: 32rem;
}

.season-feature h2 {
  color: var(--white);
  font-size: clamp(1.7rem, 2.9vw, 2.35rem);
  margin-bottom: 1rem;
}

@media (max-width: 900px) {
  .season-feature {
    grid-template-columns: 1fr;
  }

  .season-feature__media {
    min-height: 0;
    height: clamp(230px, 42vw, 330px);
  }
}

/* ------------------------------------------------------- journey links -- */

.season-callout {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.75rem;
  padding: clamp(1.1rem, 2.2vw, 1.5rem);
  background: var(--sand);
  border: 1px solid var(--line);
  border-left: 3px solid var(--turq-500);
  border-radius: var(--radius);
}

.season-callout p {
  margin: 0;
  flex: 1 1 18rem;
  font-size: 0.97rem;
  color: var(--ink-soft);
}

.season-callout__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.season-hint {
  margin: 1.5rem 0 0;
  padding: 0.85rem 1rem;
  background: var(--sand);
  border-radius: var(--radius-sm);
  font-size: 0.93rem;
  color: var(--ink-soft);
}

.season-card__contact {
  margin: -0.5rem 0 1rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--teal-700);
}

/* ------------------------------------------------- bilingual header fit -- */
/* Spanish navigation labels are markedly longer than the English ones
   ("Temporadas de Mariscos" against "Seafood Seasons"), and the 1200px
   container was clipping the header before the nav had room. The header alone
   spreads wider than the content column, and the nav runs a little tighter, so
   the horizontal layout survives Spanish rather than only English. */
.site-header .container {
  max-width: 1560px;
}

@media (min-width: 1366px) {
  .nav__list {
    gap: clamp(0.4rem, 0.95vw, 0.9rem);
  }

  .nav__link {
    font-size: 0.88rem;
  }

  .header-cta .btn {
    padding-inline: 1rem;
  }
}

/* The band between the drawer breakpoint and roughly 1400px is where the
   header is tightest: nine nav items, the language control, the logo and the
   Buyer Enquiry button all on one line. Measured in Chromium at 1280 with
   Spanish selected, the nav overran its content box by 53px once NATFISH AI
   was added as the ninth item. These three reductions recover about 80px,
   which clears it with room to spare and leaves 1400px and above untouched. */
@media (min-width: 1366px) and (max-width: 1399px) {
  .nav__list {
    gap: 0.5rem;
  }

  .nav__link {
    font-size: 0.82rem;
    letter-spacing: 0;
  }

  .header-cta .btn {
    padding-inline: 0.8rem;
    font-size: 0.82rem;
  }

  .lang-toggle {
    padding-inline: 0.6rem;
    font-size: 0.8rem;
  }
}

/* ================================================================= V2 == */
/* Components added for the client-photography update. The palette, spacing
   scale and radii all come from the existing tokens; nothing here introduces
   a second design language. */

/* ------------------------------------------------- focal-point helpers -- */
/* Seven of the ten client photographs are portrait, so a single centred crop
   loses the subject on one axis or the other. These set the crop per image and
   per breakpoint rather than settling for one compromise. */

.focus-left    { object-position: 38% 50%; }
.focus-centre  { object-position: 50% 50%; }
.focus-top     { object-position: 50% 28%; }

/* The three photographs in the second delivery whose subject will not survive
   a centred crop into the gallery's 4:3 card. Measured against the rendered
   tile rather than guessed, and written as one value each because the card is
   4:3 at every width, so unlike the crops above there is nothing to re-tune on
   a phone.

   focus-diver  0.75 portrait. The 4:3 window keeps 56% of the height. 66%
                holds the antennae, the face and the whole lobster, and gives
                up only sky above and water below.
   focus-boat   0.75 portrait. The fisher and the two raised lobsters together
                span more than the window, so something has to go: 15% keeps
                the fisher whole from raised hands to crossed legs and both
                lobster bodies, and loses only the thread-thin antenna tips.
   focus-group  16:9. The line of people is wider than the window, so the
                window is nudged left to hold the man at the end of the row. */
.focus-diver   { object-position: 50% 66%; }
.focus-boat    { object-position: 50% 15%; }
.focus-group   { object-position: 40% 50%; }

/* Third delivery.

   focus-catch-top    0.75 portrait. The fishers are working at the top of the
                      frame and the caption is about them, so the window sits
                      at the top and gives up the deepest part of the pile.
   focus-gunwale      0.5625 portrait, the tallest file in the set: the card
                      keeps only 42% of its height. High enough to hold the
                      fisher, the gunwale and the water, which is what tells
                      the viewer this is happening at sea rather than ashore.
   focus-pride-boxes  0.5625 portrait. The Belizean Pride cartons are stacked
                      in the lower half, and a centred window spends most of
                      the card on empty shelving above them. */
.focus-catch-top   { object-position: 50% 0%; }
.focus-gunwale     { object-position: 50% 30%; }
.focus-pride-boxes { object-position: 50% 90%; }

@media (max-width: 860px) {
  /* Tall frames on a phone: hold the top third, where the faces and hands are. */
  .focus-left   { object-position: 44% 38%; }
  .focus-centre { object-position: 50% 42%; }
  .focus-top    { object-position: 50% 22%; }
}

/* ------------------------------------------------------- process steps -- */
/* Four portrait photographs. They keep a 3:4 frame on every screen; forcing
   them into a landscape card is what produces the letterboxed look. */

.steps {
  display: grid;
  /* Seven steps, not four. Seven equal tracks across a 1200px container give
     roughly 150px each, and a 3:4 card at that width is 200px tall - a single
     readable row that reads as a sequence. Four tracks would have made two
     uneven rows of tall portrait cards and pushed the rest of the homepage
     down by most of a screen. */
  grid-template-columns: repeat(7, 1fr);
  gap: clamp(0.6rem, 1.4vw, 1.1rem);
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
}

.step {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  min-width: 0;
  margin: 0;
}

.step__media {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--sand-200);
  box-shadow: var(--shadow-md);
}

.step__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A step whose photograph has not been supplied yet. Same treatment as a
   product with no truthful photograph: the mark on a navy panel, so the row
   stays even and nothing is captioned as something it is not. */
.step__media--mark {
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 30% 20%, var(--navy-800) 0%, var(--navy-900) 70%);
}

.step__mark {
  width: clamp(38px, 44%, 68px);
  height: auto;
  color: var(--turq-300);
}

/* The number sits in the corner, over the darkest part of the frame rather
   than over a face, and never over the centre where the work is happening. */
.step__n {
  position: absolute;
  left: 0;
  bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9rem;
  height: 1.9rem;
  padding-inline: 0.45rem;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--white);
  background: var(--navy-900);
  border-start-end-radius: var(--radius);
}

.step__body h3 {
  font-size: 0.98rem;
  line-height: 1.3;
  margin-bottom: 0.3rem;
}

.step__body p {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

@media (min-width: 1181px) {
  /* At seven across the cards are narrow, so the badge and the copy both come
     down a step rather than crowding the frame. */
  .step__body h3 { font-size: 0.92rem; }
  .step__body p { font-size: 0.8rem; }
}

@media (max-width: 1180px) {
  .steps { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 1024px) {
  .steps { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 820px) {
  .steps { grid-template-columns: repeat(2, 1fr); }
}

/* One clean column on a phone, never a horizontal scroller: every step stays
   reachable by scrolling the page the way the rest of the site scrolls. */
@media (max-width: 620px) {
  .steps { grid-template-columns: 1fr; gap: 1.6rem; }

  .step {
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
  }

  .step__media {
    flex: 0 0 38%;
    max-width: 152px;
  }

  .step__body { padding-top: 0.15rem; }
}

/* ------------------------------------------------------ trust strip x4 -- */
/* Four items rather than three. On a phone they become a two-column grid so
   the longest label still gets a full line instead of wrapping to three. */

.trust__list--four {
  gap: 0.65rem clamp(1.1rem, 3.4vw, 3rem);
}

@media (max-width: 720px) {
  .trust__list--four {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.7rem 1.1rem;
    justify-items: start;
  }

  .trust__list--four .trust__item {
    align-items: flex-start;
    font-size: 0.84rem;
    line-height: 1.35;
  }

  .trust__list--four .ico {
    margin-top: 0.1rem;
  }
}

@media (max-width: 400px) {
  .trust__list--four { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------- product catalogue -- */

.products {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.1rem, 2.2vw, 1.75rem);
}

.product {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}


@media (hover: hover) {
  .product:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
  }
}


.product__media {
  /* 16:10 rather than 4:3. The packaging photographs are 1.5 to 2.6 wide after
     the crop that removed their invented label text, and a 4:3 frame cut the
     carton away from the conch until it read as an unidentifiable mass. */
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--sand-200);
}

.product__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Three of the six products have no photograph that would be truthful for
   them, so those cards carry the species mark on a navy panel instead of a
   borrowed or mislabelled image. The panel keeps the grid even. */
.product__media--mark {
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 30% 20%, var(--navy-800) 0%, var(--navy-900) 70%);
}

.product__mark {
  width: clamp(72px, 22%, 108px);
  height: auto;
  color: var(--turq-300);
}

.product__body {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: clamp(1.1rem, 2vw, 1.5rem);
}

.product__body h3 {
  font-size: 1.1rem;
  margin: 0;
}

.product__sci {
  margin: 0;
  font-size: 0.88rem;
  color: var(--teal-600);
}

.product__body p:not(.product__sci) {
  margin: 0.25rem 0 0;
  font-size: 0.94rem;
  color: var(--ink-soft);
}

.product__body .arrow-link {
  margin-top: auto;
  padding-top: 0.85rem;
}

@media (max-width: 1024px) {
  .products { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 620px) {
  .products { grid-template-columns: 1fr; }
}

/* The same mark panel inside the homepage card grid. */
.card__media--mark {
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 30% 20%, var(--navy-800) 0%, var(--navy-900) 70%);
}

.card__mark {
  width: clamp(64px, 26%, 96px);
  height: auto;
  color: var(--turq-300);
}

/* ------------------------------------------------------- picklist ------- */
/* The six product names on the contact page, matching the pick-list that the
   email and WhatsApp drafts carry. */

.picklist {
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.picklist li {
  font-size: 0.84rem;
  line-height: 1.3;
  padding: 0.34rem 0.68rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  color: var(--ink-soft);
}

/* ------------------------------------------------------- person card ---- */

.person-card {
  display: flex;
  gap: clamp(1rem, 2.4vw, 1.75rem);
  align-items: flex-start;
  margin-top: clamp(1.75rem, 3.5vw, 2.75rem);
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--teal-600);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.person-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--sand-100);
  color: var(--navy-800);
}

.person-card__icon .ico {
  width: 26px;
  height: 26px;
}

.person-card__body { min-width: 0; }

.person-card__body h3 {
  margin: 0.2rem 0 0.1rem;
  font-size: 1.2rem;
}

.person-card__role {
  margin: 0 0 0.75rem;
  font-size: 0.92rem;
  color: var(--teal-600);
  font-weight: 600;
}

.person-card__body p { margin: 0 0 0.5rem; }

/* Long email addresses must not push the card wider than the viewport. */
.person-card__body a {
  overflow-wrap: anywhere;
}

@media (max-width: 560px) {
  .person-card { flex-direction: column; gap: 0.9rem; }
}

/* --------------------------------------------------- contact card tags -- */

.contact-card__tag {
  display: block;
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 0.1rem;
}

.contact-card p a {
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------- footer contact -- */

.footer-list--contact li {
  line-height: 1.45;
}

.footer-list--contact a {
  overflow-wrap: anywhere;
}

.footer-tag {
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-inline-start: 0.3rem;
}

@media (max-width: 720px) {
  /* Stacked and centred on a phone, with the label under its number rather
     than trailing off the end of the line. */
  .footer-tag {
    display: block;
    margin-inline-start: 0;
  }
}

/* ---------------------------------------------------- gallery: masonry -- */
/* Seven of the ten client photographs are portrait and three are 1.6 landscape.
   In the old fixed 4:3 grid every one of them was cropped to fit, which is
   exactly what the brief rules out. Columns let each photograph keep its own
   height, so nothing is cropped, letterboxed or stretched.
   The `.gallery` grid rules above still apply to the homepage preview strip;
   only the gallery page's own figures switch to columns. */

.gallery:has(.gallery__figure) {
  display: block;
  column-count: 3;
  column-gap: clamp(0.6rem, 1.2vw, 1rem);
}

.gallery__figure {
  break-inside: avoid;
  page-break-inside: avoid;
  margin-bottom: clamp(0.6rem, 1.2vw, 1rem);
}

/* Natural proportions: no aspect-ratio, no cover crop. */
.gallery__figure .gallery__item {
  aspect-ratio: auto;
  display: block;
}

.gallery__figure .gallery__item img {
  width: 100%;
  height: auto;
  object-fit: fill;
  display: block;
}

/* The second supplied delivery is the first that is not uniformly 4:3: a 2.17
   panorama, two 0.75 portraits and three 16:9 frames. Left at their natural
   proportions they would tear ragged holes through a grid whose other cards
   are all 4:3, so anything not already 4:3 is held in the standard card and
   cropped with `cover`. The focal point is set per image further down, and the
   lightbox still opens the whole uncropped photograph.

   Same specificity as the natural-proportions rules above, so this has to sit
   after them, not before. */
.gallery__figure--crop .gallery__item {
  aspect-ratio: 4 / 3;
}

.gallery__figure--crop .gallery__item img {
  height: 100%;
  object-fit: cover;
}

@media (max-width: 860px) {
  .gallery:has(.gallery__figure) { column-count: 2; }
}

@media (max-width: 460px) {
  .gallery:has(.gallery__figure) { column-count: 1; }
}

/* --------------------------------------- the supplied gallery grid ---- */
/* The rest of the gallery is a CSS `columns` masonry, which is right for it:
   those photographs mix landscape and portrait, and masonry stops a tall one
   from leaving a hole. The client's supplied set is uniformly 1600x1200, so
   masonry buys nothing there and costs something - columns fill top-to-bottom,
   which scatters the three classifications through the layout instead of
   keeping each one together. A grid keeps DOM order, which is the client's own
   numbering, and gives exactly the one/two/three columns they asked for. */

.gallery[data-gallery-filterable] {
  display: grid;
  column-count: auto;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.9rem, 1.8vw, 1.4rem);
  align-items: start;
}

@media (max-width: 860px) {
  .gallery[data-gallery-filterable] { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 460px) {
  .gallery[data-gallery-filterable] { grid-template-columns: 1fr; }
}


/* Fallback for engines without :has(). Columns are the enhancement; the grid
   underneath still renders a usable gallery. */
@supports not selector(:has(*)) {
  .gallery__figure .gallery__item { aspect-ratio: 4 / 3; }
  .gallery__figure .gallery__item img { height: 100%; object-fit: cover; }
}

/* ------------------------------------------- portrait photography ------ */
/* --ratio carries each file's real shape and .is-portrait marks the tall ones.
   Cover-cropping a 3:4 photograph into a 4:3 frame throws away half of it,
   and the client set is mostly portrait, so the frames adapt to the pictures
   rather than the other way round. */

.split__media img.is-portrait {
  aspect-ratio: var(--ratio);
  max-height: 620px;
  object-fit: cover;
}

/* A tall photograph beside a text column should not tower over it. */
.split__media:has(img.is-portrait) {
  max-width: 480px;
  margin-inline: auto;
}

.card__media:has(img.is-portrait),
.feature-update__media:has(img.is-portrait) {
  aspect-ratio: 1 / 1;
}

.update-card__media:has(img.is-portrait) {
  aspect-ratio: 4 / 3;
}

@media (max-width: 860px) {
  /* On a phone the media sits above the copy at full width, so a tall frame
     would push the text off the first screen. Cap it. */
  .split__media img.is-portrait { max-height: 460px; }
  .split__media:has(img.is-portrait) { max-width: 380px; }
}

/* ------------------------------------------- hero focal points --------- */
/* One crop per slide, and a different one on a phone.
   At every width the hero frame is wider than it is tall but still narrower
   than the 1.78 source, so `cover` scales to the frame's height and crops the
   horizontal axis. The X value is therefore the one that decides what stays in
   frame; Y is set for completeness and has no effect at these ratios.

   Nothing is overlaid on these photographs. The hero is a split layout: the
   headline and buttons sit on their own navy panel beside the image on
   desktop, and above it on a phone. No text or control ever crosses a face,
   which is why no darkening gradient is needed over the photograph at all. */

/* All five slides are the client's responsive pairs, and no focal point is set
   on any of them at any width. On a desktop the landscape crop is served into
   a 1.6:1 frame; on a phone the portrait crop is served into a 9:16 frame that
   matches it exactly. Either way the centre is the client's own framing, and
   overriding it would undo their composition. Do not add object-position here:
   if a slide looks cropped, the frame is the wrong shape, not the focal point. */

/* ===================================================== insights ======== */
/* Two components, both built from tokens already in this file so Insights
   inherits the site's type, colour and spacing rather than introducing a
   second visual language. */

.insight-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: clamp(1.1rem, 2.4vw, 1.8rem);
  align-items: start;
}

/* The homepage preview and the landing page both currently show one article.
   A lone card stretched across a three-column grid reads as a mistake, so a
   single card is held to a readable measure and centred; when a second article
   arrives the grid takes over on its own. */
.insight-grid--feature,
.insight-grid:has(> .insight-card:only-child) {
  grid-template-columns: minmax(0, 46rem);
  justify-content: center;
}

.insight-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

@media (hover: hover) {
  .insight-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md);
    border-color: rgba(14, 124, 139, 0.34);
  }
}

/* The card's image is a second link to the same article. It is hidden from
   assistive technology and taken out of the tab order rather than duplicated,
   so a keyboard or screen-reader user meets the article once, by its title. */
.insight-card__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 9;
}

.insight-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s ease;
}

@media (hover: hover) {
  .insight-card:hover .insight-card__media img {
    transform: scale(1.04);
  }
}

.insight-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
}

.insight-card__body h2,
.insight-card__body h3 {
  font-size: clamp(1.15rem, 2.1vw, 1.4rem);
  margin: 0;
}

.insight-card__body h2 a,
.insight-card__body h3 a {
  color: inherit;
  text-decoration: none;
}

.insight-card__body h2 a:hover,
.insight-card__body h3 a:hover {
  text-decoration: underline;
}

.insight-card__body p {
  margin: 0;
  color: var(--ink-soft);
}

.insight-card__body .arrow-link {
  margin-top: 0.2rem;
}

/* ------------------------------------------------------- breadcrumb ---- */

.breadcrumb {
  margin-bottom: clamp(1.2rem, 2.6vw, 1.8rem);
}

.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.breadcrumb li + li::before {
  content: "/";
  margin-right: 0.55rem;
  color: var(--line-strong, rgba(16, 41, 58, 0.35));
}

.breadcrumb a {
  color: var(--teal-600);
}

.breadcrumb [aria-current="page"] {
  color: var(--ink-soft);
}

/* ---------------------------------------------------------- article ---- */

.article {
  padding-block: clamp(2rem, 5vw, 3.4rem);
}

.article__head h1 {
  margin-block: 0.3rem 0.6rem;
}

.article__byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.article__dot {
  opacity: 0.5;
}

.article__figure {
  margin: clamp(1.6rem, 4vw, 2.6rem) 0;
}

.article__figure picture,
.article__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
}

/* Body copy at a readable measure. The container is already narrow; this holds
   the line length in the 60-75 character band even on a wide desktop. */
.article__body {
  max-width: 68ch;
}

.article__body h2 {
  font-size: clamp(1.35rem, 2.6vw, 1.75rem);
  margin-block: clamp(1.8rem, 3.6vw, 2.4rem) 0.7rem;
}

.article__body p {
  margin-block: 0 1.05rem;
  line-height: 1.75;
}

.article__list {
  margin-block: 0 1.05rem;
  padding-left: 1.15rem;
  line-height: 1.75;
}

.article__list li {
  margin-bottom: 0.45rem;
}

.article__body > *:last-child {
  margin-bottom: 0;
}

/* ================================================== NATFISH AI ======== */

/* --------------------------------------------- the floating launcher -- */
/* A capsule with the NATFISH mark in a white badge on the left and the call
   to action in the site's own body face. Navy-to-teal from the existing
   tokens, so it reads as part of NATFISH on light, sand, navy and photographic
   backgrounds alike.

   MOTION. The pill swims: a slow horizontal drift across the foot of the
   viewport with a gentle vertical bob over the top of it, the way a fish moves
   forward while rising and falling. Those are two different speeds on the same
   property, and one element cannot run two transform animations, so the outer
   anchor drifts and the inner .ai-pill__body bobs.

   The drift WRAPS rather than bouncing: the loop runs from fully off screen on
   the left to fully off screen on the right, one-directional, so the fish
   never reverses. The keyframe loop's own to->from jump happens while the pill
   is entirely hidden, and the endpoints are computed so that the instant its
   tail clears the right edge its nose is at the left edge - it leaves and
   re-enters in the same moment.

   THE LOOP IS LINEAR END TO END, at a constant 28px/s, and that is a client
   decision rather than a default. A four-stop keyframe was tried, to shorten
   the part of each lap the pill spends off frame; it was reverted because it
   changed the one number the client actually times. A full transit - nose
   appearing at the left edge to tail clearing the right - is almost exactly
   **20 seconds on a 390px phone**, which they measured and approved: "any
   faster or slower breaks it." A wide screen takes proportionally longer,
   about 58s at 1440px, at the same pace.

   The trade this accepts, knowingly: a wrap travels viewport + pill while only
   viewport - pill of that is fully on screen, so on a phone the launcher is
   fully visible for roughly 39% of each lap and off frame or clipped for the
   rest. That is the cost of a true wrap on a narrow screen at a fixed pace, and
   it is the behaviour the client timed and asked to keep.

   All four custom properties are set by natfish-ai.js from the measured pill
   and viewport widths and updated on resize and language change:
     --ai-out-left    fully hidden past the left edge (loop start)
     --ai-out-right   fully hidden past the right edge (loop end)
     --ai-travel      the resting position at the right margin (docking only)
     --ai-dur         loop duration, scaled to the distance so the speed is
                      the same on a phone and a desktop
     --ai-delay       negative offset placing the pill within the loop: at the
                      left margin on load, at the right margin on resume

   The pill is position: fixed, which is what makes the off-screen excursion
   safe: fixed elements never extend the document's scrollable area, so there
   is no horizontal overflow to create.

   On click the pill docks: it glides to the right margin and the chat panel
   opens beside it. When the panel is CLOSED the pill swims off again from the
   docked position - natfish-ai.js re-enters the loop at the matching offset,
   so it continues rightward, wraps, and carries on. */

.ai-pill {
  position: fixed;
  z-index: 60;                 /* over content, under the header and panel */
  left: max(1rem, env(safe-area-inset-left));
  bottom: max(1rem, env(safe-area-inset-bottom));
  /* All replaced at runtime; the zeros mean "hold still until measured". */
  --ai-travel: 0px;
  --ai-out-left: 0px;
  --ai-out-right: 0px;
  --ai-dur: 60s;
  --ai-delay: 0s;
  display: inline-flex;
  align-items: center;
  min-height: 56px;            /* comfortably past the 44px minimum */
  max-width: calc(100vw - 2rem);
  padding: 0.45rem 1.15rem 0.45rem 0.45rem;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: linear-gradient(135deg, var(--navy-800) 0%, var(--teal-600) 100%);
  box-shadow: 0 10px 26px rgba(3, 25, 42, 0.3);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  will-change: transform;
  /* The per-keyframe timing functions above own the easing; this one only
     covers any gap they do not. */
  animation: ai-swim var(--ai-dur) linear infinite;
  animation-delay: var(--ai-delay);
}

.ai-pill__body {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  animation: ai-bob 2.9s ease-in-out infinite alternate;
}


@media (hover: hover) {
  /* Only the shadow deepens on hover. Nothing about the pill's own transform
     changes, because that belongs to the swim. */
  .ai-pill:hover {
    box-shadow: 0 14px 32px rgba(3, 25, 42, 0.4);
  }
}


/* The site's own focus treatment, not a new one. */
.ai-pill:focus-visible {
  outline: 3px solid var(--turq-300);
  outline-offset: 3px;
}


@media (hover: hover) {
  /* A drifting target is a hard target. Both motions stop the moment a pointer
     or the keyboard reaches the pill, and resume when it leaves. */
  .ai-pill:hover,
  .ai-pill:focus-visible,
  .ai-pill:hover .ai-pill__body,
  .ai-pill:focus-visible .ai-pill__body {
    animation-play-state: paused;
  }
}


/* Docking. .is-docking swaps the animation for a transition so the pill glides
   from wherever it was rather than jumping; .is-docked is the resting place at
   the right margin. It stays docked only while the panel is open - a launcher
   that swam away from an open chat would be absurd - and resumes the swim from
   that spot when the panel closes. */
.ai-pill.is-docking,
.ai-pill.is-docking .ai-pill__body {
  animation: none;
}

.ai-pill.is-docking {
  transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.ai-pill.is-docked {
  transform: translateX(var(--ai-travel));
}

@keyframes ai-swim {
  from { transform: translateX(var(--ai-out-left)); }
  to   { transform: translateX(var(--ai-out-right)); }
}

/* The wobble. Amplitude is deliberately larger than it first was: against a
   slow crossing a 3px rise was invisible, and the rise and fall is what reads
   as swimming rather than sliding. It is the inner body that moves, because
   the outer anchor already owns transform for the drift. */
@keyframes ai-bob {
  from { transform: translateY(7px); }
  to   { transform: translateY(-7px); }
}

/* Reduced motion: no swim, no bob. The pill simply rests at the right margin,
   which is where a docked pill ends up anyway. */
@media (prefers-reduced-motion: reduce) {
  .ai-pill,
  .ai-pill__body {
    animation: none;
  }

  .ai-pill {
    transform: translateX(var(--ai-travel));
    transition: none;
  }
}

/* The emblem carries a lobster, a hand, a cuff and a wave ring - a lot of
   drawing for a small circle, and at 34px inside 44px it read as a smudge on a
   real screen rather than as the NATFISH mark. Both the circle and the artwork
   inside it are larger, and the artwork now uses more of the circle it sits
   in. */
.ai-pill__badge {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--white);
  overflow: hidden;
}

.ai-pill__badge img {
  width: 44px;
  height: 44px;
  object-fit: contain;
}

.ai-pill__label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 720px) {
  .ai-pill {
    min-height: 52px;
    padding: 0.4rem 0.95rem 0.4rem 0.4rem;
    font-size: 0.94rem;
  }

  .ai-pill__body { gap: 0.5rem; }
  .ai-pill__badge { width: 48px; height: 48px; }
  .ai-pill__badge img { width: 40px; height: 40px; }
}

/* Below 380px the label plus the badge would reach the opposite gutter, so
   the capsule tightens rather than wrapping or overflowing. */
@media (max-width: 380px) {
  .ai-pill {
    left: max(0.65rem, env(safe-area-inset-left));
    bottom: max(0.65rem, env(safe-area-inset-bottom));
    max-width: calc(100vw - 1.3rem);
    font-size: 0.88rem;
    padding-right: 0.8rem;
  }
}

/* The footer's last line would otherwise sit under the pill on a phone. */
@media (max-width: 720px) {
  .site-credit { padding-bottom: 4.5rem; }
}

/* ----------------------------------------------- NATFISH AI page ------ */

/* The disclosure directly under the hero CTA. Deliberately plain: it is a
   statement of what the assistant is, not a warning box. */
.ai-note {
  margin: 1.15rem 0 0;
  padding: 0.85rem 1.1rem;
  border-inline-start: 3px solid var(--turq-500);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: rgba(34, 167, 188, 0.09);
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 56ch;
}

.section--navy .ai-note,
.hero__panel .ai-note {
  background: rgba(255, 255, 255, 0.08);
  border-inline-start-color: var(--turq-300);
  color: rgba(255, 255, 255, 0.86);
}

/* The four capability cards. Same rhythm as .pillar, with the mark on an open
   baseline rather than in yet another rounded tile. */
.ai-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.1rem, 2.2vw, 1.75rem);
}

@media (max-width: 1024px) {
  .ai-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
  .ai-grid { grid-template-columns: 1fr; }
}

/* Numbered three-step sequence. */
.ai-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.25rem, 2.6vw, 2.25rem);
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: ai-step;
}

.ai-steps > li {
  margin: 0;
  min-width: 0;
  padding-top: 1.15rem;
  border-top: 2px solid var(--line);
}

.ai-steps > li::before {
  counter-increment: ai-step;
  content: counter(ai-step, decimal-leading-zero);
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--turq-500);
}

.ai-steps h3 { font-size: 1.05rem; margin-bottom: 0.35rem; }
.ai-steps p { margin: 0; font-size: 0.94rem; color: var(--ink-soft); }

@media (max-width: 720px) {
  .ai-steps { grid-template-columns: 1fr; gap: 1.4rem; }
}

/* The privacy section. Plain language on the sand ground the site already
   uses for supporting material, not fine print in a grey box. */
.ai-privacy {
  display: grid;
  gap: 1rem;
  max-width: 68ch;
}

.ai-privacy p { margin: 0; }

/* The product list on the AI page: compact, two columns, no card chrome. */
.ai-products {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem clamp(1.5rem, 3vw, 3rem);
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
}

.ai-products li {
  display: flex;
  gap: 0.55rem;
  align-items: baseline;
  padding-block: 0.35rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.96rem;
}

.ai-products .ico {
  width: 17px;
  height: 17px;
  align-self: center;
  color: var(--teal-600);
}

@media (max-width: 620px) {
  .ai-products { grid-template-columns: 1fr; }
}

/* --------------------------------------------- four contact options --- */
/* The contact grid went from three cards to four when NATFISH AI joined the
   verified telephone, email and address routes. Four across only above
   1100px; below that it is two-by-two, then a single column, because four
   cards squeezed into a 1024px row give each one about 230px and the
   telephone numbers start wrapping mid-number. */

.grid--4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.1rem, 2.2vw, 1.75rem);
}

.grid--4 > * { min-width: 0; }

@media (max-width: 1100px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
  .grid--4 { grid-template-columns: 1fr; }
}

/* One teal edge marks the assistant as the new option. Everything else about
   the card matches its neighbours, so it introduces the service without
   outranking the numbers a buyer actually needs. */
.contact-card--ai {
  border-inline-start: 3px solid var(--teal-600);
}

.contact-card--ai .note {
  font-size: 0.84rem;
  margin-top: 0.5rem;
}

.contact-card__action {
  margin-top: 0.95rem;
  margin-bottom: 0.25rem;
}

/* The button carries its own icon, so it needs the same optical spacing the
   other icon-bearing buttons use. */
.contact-card__action .btn { width: 100%; }

/* The secondary route under the hero call to action. A sentence with a link,
   deliberately not a second button: two buttons side by side would make the
   human contact route compete with the assistant instead of sitting behind
   it. */
.ai-secondary {
  margin: 0.9rem 0 0;
  font-size: 0.96rem;
  color: var(--ink-soft);
}

.ai-secondary a {
  color: var(--teal-700);
  font-weight: 600;
}

/* Four cards across leaves each one about 198px of inner width, and
   nationalfishermen@gmail.com needs 201px at the body size: three pixels
   short, so it broke mid-word into "gmail.co / m". A small step down on the
   address only -- the telephone numbers keep their size -- puts it back on one
   line. Below 1100px the cards are wide again and this does not apply. */
@media (min-width: 1101px) {
  .grid--4 .contact-card a[href^="mailto:"] {
    font-size: 0.9rem;
  }
}

/* --------------------------------------- alignment under centred heads -- */
/* Centring a heading and leaving the block beneath it hard against the left
   gutter looks like an accident. These centre the block while keeping the text
   inside it left-aligned, because centred body copy is genuinely harder to
   read: the eye loses the start of each new line. */

.ai-privacy {
  margin-inline: auto;
}

.container--narrow .ai-note {
  margin-inline: auto;
}

/* Nothing left to colour here now that the rule is gone; the centred variant
   differs from the plain one only in alignment. */

/* ------------------------------------- .pillar on a light background ---- */
/* The pillar component was written for .section--navy and hard-codes
   light-on-dark: rgba(255,255,255,.82) body text and a turq-300 icon. Reusing
   it on the sand NATFISH AI section rendered four cards whose paragraphs were
   white on near-white -- present in the DOM, invisible on screen.
   The dark treatment now belongs to dark sections, and the default is the
   ordinary body colour, so the component can sit on either ground. */

.pillar p {
  color: var(--ink-soft);
}

.pillar__icon {
  color: var(--teal-600);
  border-bottom-color: rgba(14, 124, 139, 0.45);
}

.section--navy .pillar p,
.hero .pillar p {
  color: var(--ink-onDark);
}

.section--navy .pillar__icon,
.hero .pillar__icon {
  color: var(--turq-300);
  border-bottom-color: rgba(34, 167, 188, 0.5);
}

/* ============================================ contrast corrections ===== */
/* Three failures found by measuring every text node against its composited
   background, rather than by eye. All three came from a rule written for one
   context leaking into another. */

/* 1. The main call to action on almost every page. `.section--navy a` sets
      turquoise for links on navy, and the primary button is an anchor, so it
      inherited turquoise text on its own teal fill: 2.98:1, well under the
      4.5:1 a 15px label needs. Buttons carry their own colour and are excluded
      from the link rule; the fix is one selector, not a new button variant. */
.section--navy a:not(.btn) {
  color: var(--turq-300);
}


@media (hover: hover) {
  .section--navy a:not(.btn):hover {
    color: var(--white);
  }
}


.section--navy .btn--primary {
  color: var(--white);
}

/* 2. `.btn--ghost` is the light-on-dark variant, and the Responsible Fisheries
      page closes on a sand band: white text on near-white, 1.07:1, effectively
      an invisible button. The ghost now defaults to dark-on-light and the
      white treatment is scoped to the grounds that are actually dark. */
.btn--ghost {
  border-color: rgba(5, 43, 69, 0.35);
  color: var(--navy-800);
}


@media (hover: hover) {
  .btn--ghost:hover {
    background: rgba(5, 43, 69, 0.06);
    border-color: var(--navy-800);
    color: var(--navy-900);
  }
}


.section--navy .btn--ghost,
.hero__panel .btn--ghost,
.season-feature__panel .btn--ghost,
.site-footer .btn--ghost {
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--white);
}


@media (hover: hover) {
  .section--navy .btn--ghost:hover,
  .hero__panel .btn--ghost:hover,
  .season-feature__panel .btn--ghost:hover,
  .site-footer .btn--ghost:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: var(--white);
    color: var(--white);
  }
}


/* 3. The cooperative-model step numbers ran turquoise-500 on white at 11px:
      2.87:1. Same hue, two steps darker, which keeps the accent without
      making the label a guess. */
.flow__num {
  color: var(--teal-700);
}

.section--navy .flow__num {
  color: var(--turq-300);
}

/* ================================ centring pass ======================== */

/* Icons in a card grid are centred. The site had both treatments -- the
   Seafood & Services pillars used the centred variant while the NATFISH AI
   cards used the plain one, so the same component read two different ways on
   two pages. Centred is now the base, because every place .pillar is used it
   is a card in a symmetric grid. .pillar--center still resolves, so existing
   markup keeps working. */

.pillar {
  text-align: center;
}

.pillar__icon {
  justify-content: center;
  align-self: center;
  margin-inline: auto;
  /* The rule under the mark is part of the mark, so it centres with it rather
     than running to the card's left edge. */
  padding-inline: 1.5rem;
}

/* The three-step sequence on the NATFISH AI page: the numeral, heading and
   copy centre together, and the rule above each step spans the column so the
   numeral sits centred on it. */
.ai-steps > li {
  text-align: center;
}

.ai-steps > li::before {
  margin-inline: auto;
}

/* Numbered step cards on the home page keep their corner badge: it sits over
   the photograph, where centring would put it across the middle of the frame.
   Their captions centre with everything else. */
/* Left, not centred. The step copy was centred while there were four wide
   cards. The client's sequence is seven, so the columns are now about 150px
   across at desktop and a four-line paragraph centred in one is ragged on both
   edges -- the same reason the phone layout had already been excepted. One
   rule now covers every width. */
.step__body {
  text-align: left;
}

/* ------------------------------------------------- the assistant button -- */
/* Distinct from btn--primary so the assistant does not look like a third
   identical teal button beside Send an Email. Navy-to-teal, matching the
   floating launcher, so the two read as the same thing in two places. */

.btn--ai {
  border-color: transparent;
  background: linear-gradient(135deg, var(--navy-800) 0%, var(--teal-600) 100%);
  color: var(--white);
}


@media (hover: hover) {
  .btn--ai:hover {
    background: linear-gradient(135deg, var(--navy-900) 0%, var(--teal-700) 100%);
    color: var(--white);
  }
}


.section--navy .btn--ai {
  color: var(--white);
}

/* ------------------------------------------------- page hero actions --- */
/* Calls to action inside the banner, not stranded on white beneath it. */

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem 1.25rem;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

.page-hero__actions .arrow-link {
  color: var(--turq-300);
}


@media (hover: hover) {
  .page-hero__actions .arrow-link:hover {
    color: var(--white);
  }
}


/* ------------------------------------------------ per-product ordering -- */
/* A product card ends with two actions, not one: start the order here, or
   take the same product to email or WhatsApp. The order button sits first
   because it is the route that answers immediately.
   margin-top:auto on the wrapper is what keeps the buttons on a common
   baseline across a row of cards whose descriptions differ in length. */

.product__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 1rem;
}

.product__actions .btn {
  width: 100%;
  justify-content: center;
}

/* Overrides the generic rule above, which would otherwise push the enquiry
   link to the bottom of the card on its own. */
.product__body .product__actions .arrow-link {
  margin-top: 0;
  padding-top: 0;
  font-size: 0.88rem;
}

/* ------------------------------------------------- order pick list ------ */
/* The approved products on the NATFISH AI page, as a list of rows a visitor
   can act on one at a time. Deliberately not the card grid from Seafood &
   Services: this is a chooser, and six photographs here would compete with
   the single decision the section is asking for. */

.order-list {
  list-style: none;
  margin: clamp(1.75rem, 3.5vw, 2.5rem) 0 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.order-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  padding: clamp(0.9rem, 2vw, 1.15rem) clamp(1rem, 2.4vw, 1.5rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}


@media (hover: hover) {
  .order-item:hover {
    border-color: var(--teal-600);
    box-shadow: var(--shadow-md);
  }
}


/* The product thumbnail. 96px square: large enough to identify a carton of
   lobster tails at a glance, small enough that six of them stay a list rather
   than becoming a second product grid. */
.order-item__media {
  flex: 0 0 auto;
  width: 96px;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius-md, 12px);
  background: var(--sand-200);
}

.order-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Where no truthful photograph exists, the species mark on navy - the same
   substitution the product cards make. */
.order-item__media--mark {
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 30% 20%, var(--navy-800) 0%, var(--navy-900) 70%);
}

.order-item__mark {
  width: 52%;
  height: auto;
  color: var(--turq-300);
}

.order-item__name {
  min-width: 0;
  /* flex-basis only along the row axis. When the row becomes a column below
     560px this must be reset, or a 16rem basis is read as a 256px HEIGHT and
     each item grows a tall empty band between its name and its button. */
  flex: 1 1 16rem;
}

.order-item__name h3 {
  margin: 0;
  font-size: 1.02rem;
}

.order-item__name .product__sci {
  margin-top: 0.1rem;
}

.order-item .btn {
  flex: 0 0 auto;
}

.order-list__cta {
  margin: clamp(1.5rem, 3vw, 2.25rem) 0 0;
  text-align: center;
}

@media (max-width: 560px) {
  .order-item {
    /* Below this width the button no longer fits beside the name without the
       label wrapping to two lines, so the row becomes a stack and the button
       spans it. */
    flex-direction: column;
    align-items: stretch;
  }

  /* The main axis is now vertical, so every flex shorthand above that carried
     a horizontal basis has to be neutralised. Leaving .order-item__name at
     "1 1 16rem" here is what put a 256px empty band inside each card. */
  .order-item__name {
    flex: 0 0 auto;
  }

  .order-item__media {
    width: 100%;
    /* A wide crop rather than a square: full width at 1:1 is a huge block of
       carton, and the shape of the packaging reads better letterboxed. */
    aspect-ratio: 16 / 9;
  }

  .order-item__mark {
    width: clamp(64px, 22%, 96px);
  }

  .order-item .btn {
    width: 100%;
    justify-content: center;
  }
}

/* ------------------------------------------------------ ordering paths -- */
/* Two routes to the same team. The assistant leads on colour and weight; the
   human route is quieter but never smaller, because someone who wants a person
   should not have to look for one. */

.paths {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem);
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  align-items: start;
}

@media (max-width: 900px) {
  .paths {
    grid-template-columns: 1fr;
  }
}

.path {
  display: flex;
  flex-direction: column;
  min-width: 0;
  height: 100%;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.path h3 {
  font-size: clamp(1.25rem, 2.4vw, 1.5rem);
  margin: 0.75rem 0 0.6rem;
}

.path > p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.98rem;
}

.path__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
}

.path__icon svg {
  width: 22px;
  height: 22px;
}

/* A label, not a badge of status: "Available online" describes the route, and
   nothing here claims stock, a price or an accepted order. */
.path__tag {
  align-self: flex-start;
  margin-bottom: 0.9rem;
  padding: 0.28rem 0.7rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.path__action {
  margin: clamp(1.25rem, 2.5vw, 1.75rem) 0 0.9rem;
}

.path__action .btn {
  width: 100%;
  justify-content: center;
}

.path__action--stack {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.path .note {
  margin-top: auto;
  padding-top: 0.35rem;
  margin-bottom: 0;
}

.path .arrow-link {
  margin-top: 0.35rem;
}

/* -- path one: the assistant ------------------------------------------- */

.path--ai {
  color: var(--white);
  border: 1px solid transparent;
  background:
    radial-gradient(120% 130% at 15% 0%, var(--navy-800) 0%, var(--navy-900) 68%);
}

.path--ai h3,
.path--ai h4 {
  color: var(--white);
}

.path--ai > p {
  color: rgba(255, 255, 255, 0.86);
}

.path--ai .path__tag {
  background: var(--turq-300);
  color: var(--navy-900);
}

.path--ai .path__icon {
  background: rgba(34, 167, 188, 0.18);
  color: var(--turq-300);
}

.path--ai .arrow-link {
  color: var(--turq-300);
}


@media (hover: hover) {
  .path--ai .arrow-link:hover {
    color: var(--white);
  }
}


/* The "Have these ready" panel: a lighter plate inside the navy card so the
   four lines read as a checklist rather than as more body copy. */
.path__ready {
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  padding: clamp(1rem, 2.2vw, 1.35rem);
  border-radius: var(--radius-md, 12px);
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.14);
}

.path__ready h4 {
  margin: 0 0 0.8rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.path--ai .path__ready .checklist li {
  color: rgba(255, 255, 255, 0.9);
}

.path--ai .path__ready .checklist svg,
.path--ai .path__ready .checklist .ico {
  color: var(--turq-300);
}

/* -- path two: the team ------------------------------------------------- */

.path--team {
  background: var(--white);
  border: 1px solid var(--line);
  border-block-start: 4px solid var(--teal-600);
}

.path--team .path__tag {
  background: var(--sand);
  color: var(--teal-700);
}

.path--team .path__icon {
  background: var(--sand);
  color: var(--teal-700);
}

/* ------------------------------------------------ two-column checklist -- */
/* Nine items in a single column made the aside taller than the copy beside
   it. Two columns above 560px keeps the two halves of the block level. */

/* Multi-column rather than a two-column grid. A grid gives every row the
   height of its tallest cell, so items that wrap to two lines leave gaps
   beside the ones that do not; columns pack the nine items tightly and, more
   importantly, flow top-to-bottom down each column, which is how a list is
   read. break-inside stops an item being split across the column fold. */
.checklist--two {
  columns: 2;
  column-gap: 1.75rem;
}

.checklist--two li {
  break-inside: avoid;
}

@media (max-width: 620px) {
  .checklist--two {
    columns: 1;
  }
}

/* The checklist panel is sand by default, which disappears when the section
   itself is sand. */
.section--sand .enquiry__checklist {
  background: var(--white);
}

/* ------------------------------------------------- the assistant panel -- */
/* The client supplied Chatbase's IFRAME embed, which has no JavaScript API
   and no launcher of its own, so the floating panel that holds it is ours.
   Only the chrome is ours: the conversation inside is Chatbase's iframe at
   Chatbase's URL, untouched. */

/* Catches the tap beside the sheet. Without it the panel is a trap on a
   phone: it covers the page, the launcher is hidden behind it, and Escape
   stops working as soon as the visitor taps into the cross-origin chat. */
.ai-backdrop {
  position: fixed;
  z-index: 149;                     /* directly beneath the panel */
  inset: 0;
  background: rgba(3, 25, 42, 0.38);
  opacity: 0;
  transition: opacity 0.22s ease;
}

.ai-backdrop.is-open {
  opacity: 1;
}

/* Above the small breakpoint the panel is a corner card, not a takeover, so a
   dimmed page would overstate it. The element stays - it is still what makes a
   click beside the panel close it - but it is invisible. */
@media (min-width: 561px) {
  .ai-backdrop {
    background: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ai-backdrop {
    transition: none;
  }
}

/* THE hidden ATTRIBUTE NEEDS HELP HERE, and leaving it out was a real bug.
   The browser's own [hidden] rule is display:none at UA level, so ANY author
   rule that sets display on the same element beats it. .ai-panel sets
   display:flex, so panel.hidden = true had no effect at all: after the first
   time a visitor opened the assistant, the closed panel stayed laid out at
   88% of the height of a phone screen - invisible at opacity 0, and swallowing
   every tap over that area. The page looked frozen from the first interaction
   onward. The same trap is why .ai-backdrop deliberately sets no display
   property of its own. */
.ai-panel[hidden],
.ai-backdrop[hidden] {
  display: none;
}

.ai-panel {
  position: fixed;
  /* Above the sticky header (100) so the panel is never clipped by it, and
     below the mobile nav drawer (200) and the lightbox (999), both of which
     should win if they are opened over it. */
  z-index: 150;
  right: max(1rem, env(safe-area-inset-right));
  bottom: calc(max(1rem, env(safe-area-inset-bottom)) + 76px);
  width: min(420px, calc(100vw - 2rem));
  /* dvh, with vh as the fallback for browsers without it. On a phone 100vh is
     the LARGE viewport - it ignores the browser's own toolbars - so sizing
     against it can push the top of the sheet, and with it the close control,
     off the visible screen. That is how the only way out of the panel
     disappears. */
  /* Above the phone breakpoint the backdrop is transparent, so the header is
     visible AND still clickable, and the close button genuinely must stay off
     it - this panel is a corner card, not a takeover. The reserve is the 92px
     bottom offset, an 88px header and the button's 62px: 16rem, measured, and
     12 was tried and put the button through the header at 1440x900.

     The cap is what moved. 660px left a tall desktop with the panel ending
     well short of the space available; 720px uses it, and on any window short
     enough for the reserve to bind, the reserve still wins. */
  height: min(720px, calc(100vh - 16rem));
  height: min(720px, calc(100dvh - 16rem));
  display: flex;
  flex-direction: column;
  /* NOT overflow:hidden. The close button sits above the panel's top edge so
     it cannot cover the iframe's own header controls, and clipping here would
     hide it. The rounding and clipping belong to the body instead. */
  background: var(--white);
  box-shadow: 0 24px 60px rgba(3, 25, 42, 0.28);
  border-radius: var(--radius-lg);
  opacity: 0;
  transform: translateY(12px) scale(0.985);
  transition: opacity 0.22s ease, transform 0.22s ease;
}

.ai-panel.is-open {
  opacity: 1;
  transform: none;
}

/* The only chrome we add. It sits ABOVE the panel's top edge, clear of the
   Chatbase header inside the frame - which carries the agent's own name and
   its own menu at the same corner - so nothing is covered and there is only
   one header on screen. Deliberately large: it is the one exit the host page
   controls, because Escape stops working as soon as the visitor taps into the
   cross-origin frame. */
.ai-panel__close {
  position: absolute;
  bottom: calc(100% + 0.6rem);
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-radius: 50%;
  background: var(--navy-900);
  color: var(--white);
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(3, 25, 42, 0.45);
  transition: background 0.18s ease, transform 0.18s ease;
}


@media (hover: hover) {
  .ai-panel__close:hover {
    background: var(--teal-700);
    transform: scale(1.06);
  }
}


.ai-panel__close svg {
  width: 24px;
  height: 24px;
}

/* The body now owns the rounding and the clipping the panel used to. */
.ai-panel__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--sand);
}

/* One rule for both the panel frame and the in-page one. */
.ai-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* On a phone the panel is the screen. Anything narrower than a full-width
   sheet puts the agent's own input field into a column too narrow to type
   in comfortably. */
@media (max-width: 560px) {
  .ai-panel {
    right: 0;
    left: 0;
    bottom: 0;
    width: auto;
    /* Same reasoning as above: dvh tracks the visible viewport as the
       browser's toolbars come and go, so the close control stays reachable.
       The vh line is the fallback, and is deliberately the more conservative
       of the two.

       The reserve covers the close button, and nothing else. It used to cover
       the sticky header too, on the theory that the button must not land on
       the header's own controls - but .ai-backdrop is z-index 149, inset 0,
       and the header is sticky at 100, so the moment the sheet opens the
       header is already dimmed and already untappable. Reserving room for
       controls nobody can reach cost 100px of sheet on every phone and left
       the panel starting a third of the way down a 568px screen.

       5.5rem (88px) is the button's own 52px, its 0.6rem gap, and enough left
       over that it never crowds the top of the viewport. At 320x568 that is a
       480px sheet - 85% of the screen - with the button at y=26. */
    height: min(94vh, 100vh - 5.5rem);
    height: min(94dvh, 100dvh - 5.5rem);
    border-radius: 0;
  }

  .ai-panel__body {
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-inline-width: 0;
    border-block-end-width: 0;
  }

  /* Inset from the screen edge on a phone, where right: 0 would put it under
     the thumb's own edge-swipe zone. */
  .ai-panel__close {
    right: 0.85rem;
  }

  /* The launcher would sit on top of the sheet it just opened. */
  .ai-panel-open .ai-pill {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ai-panel {
    transition: none;
  }
}

/* --------------------------------------------------- the inline embed -- */
/* natfish-ai.html runs the same embed in the page, which is what this embed
   form is designed for. min-height 700px comes from the supplied embed and is
   the height the agent's own layout expects; the viewport clamp above it stops
   the frame growing taller than the screen on a phone. */

.ai-embed {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--white);
  box-shadow: var(--shadow-md);
}

.ai-embed:focus-visible {
  outline: 3px solid var(--teal-600);
  outline-offset: 3px;
}

.ai-embed__frame {
  height: min(700px, calc(100vh - 10rem));
  min-height: 520px;
  background: var(--sand);
}

.ai-embed__note {
  margin: 0.9rem 0 0;
  text-align: center;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

/* The stand-in shown where the embed cannot load: the artifact preview only,
   which is one file under a CSP that blocks every external host. */
.ai-blocked {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
  height: 100%;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.ai-blocked p {
  margin: 0;
}

.ai-blocked__title {
  font-weight: 700;
  color: var(--navy-900);
}

/* ---------------------------------------------------------------- FAQ --
   <details>/<summary>, so the whole component is keyboard-operable and
   announced correctly with no JavaScript at all. The answer stays in the DOM
   when the item is shut, which is what search-in-page and an answer engine
   both need, and it is what lets the FAQPage markup be honest about the page
   showing every answer.

   summary::-webkit-details-marker is cleared because the disclosure state is
   carried by the chevron instead; `list-style: none` does the same job in
   Firefox. */

.faq {
  display: grid;
  gap: 0.75rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}

.faq__item {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.section--sand .faq__item {
  border-color: var(--sand-200);
}

.faq__item[open] {
  border-color: rgba(14, 124, 139, 0.35);
  box-shadow: var(--shadow-md);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem clamp(1rem, 2.5vw, 1.5rem);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.02rem, 1.5vw, 1.12rem);
  line-height: 1.35;
  color: var(--navy-900);
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q:hover {
  color: var(--teal-700);
}

.faq__q:focus-visible {
  outline: 3px solid var(--teal-600);
  outline-offset: -3px;
}

.faq__chev {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--teal-600);
  transition: transform 0.22s ease;
}

.faq__item[open] .faq__chev {
  transform: rotate(180deg);
}

.faq__a {
  padding: 0 clamp(1rem, 2.5vw, 1.5rem) 1.25rem;
}

.faq__a p {
  margin: 0;
  max-width: 62ch;
  color: var(--ink-soft);
}

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