/* ==========================================================================
   Euro Premium Energy S.A.
   Design system & site styles
   Built on Bootstrap 5.3
   --------------------------------------------------------------------------
   Palette is anchored to the brand mark (navy #02173B) with a warm brass
   accent. Corners are square throughout — an institutional, non-consumer
   register in keeping with the reference sites.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand */
  --epe-navy:        #02173b;   /* sampled from the logo */
  --epe-navy-900:    #010f28;
  --epe-navy-800:    #04204f;
  --epe-navy-700:    #0a2c65;
  --epe-brass:       #c0a16b;   /* on navy */
  --epe-brass-light: #d6bd8e;
  --epe-brass-ink:   #755c30;   /* on light grounds — brass itself only reaches 2.2:1 there */
  --epe-green:       #4f7f63;
  --epe-green-light: #7fae91;

  /* Neutrals */
  --epe-paper:       #ffffff;
  --epe-bone:        #f4f4f2;   /* Trafigura-style neutral ground */
  --epe-tint:        #ececeA;
  --epe-line:        #dcdcd8;
  --epe-line-dark:   rgba(255, 255, 255, .16);
  --epe-ink:         #141414;
  --epe-ink-soft:    #4a4f57;
  --epe-ink-mute:    #5f646c;   /* darkened from #767b83 to clear 4.5:1 at label sizes */

  /* Type */
  --font-display: "Outfit", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "Inter", "Helvetica Neue", Arial, sans-serif;
  --font-serif:   "Cormorant Garamond", Georgia, serif;

  /* Type scale — every font-size on the site comes from this list. Sizing a
     component "by eye" is what produced nine sizes inside a 2px range; pick the
     nearest step instead, and if none fits, the scale is what needs changing. */
  --fs-2xs:    .68rem;   /* micro caps: brand sub-line, HQ keys, product chips  */
  --fs-xs:     .72rem;   /* caps labels: eyebrows, form labels, contact keys    */
  --fs-sm:     .80rem;   /* small UI: buttons, numerals, stat labels, feedback  */
  --fs-base:   .92rem;   /* secondary body: footer, notes, nav, form controls   */
  --fs-md:     1rem;     /* body copy                                          */
  --fs-lg:     1.15rem;  /* sub-heads: card headings, contact company          */
  --fs-lead:   clamp(1.05rem, 1.45vw, 1.22rem);  /* standfirst paragraphs      */
  --fs-title:  clamp(1.15rem, 1.9vw, 1.5rem);    /* card titles                */
  --fs-quote:  clamp(1.45rem, 3vw, 2.4rem);      /* serif pull-quote           */
  --fs-h2:     clamp(1.9rem, 3.6vw, 3.05rem);    /* section headings           */
  --fs-h1:     clamp(2.05rem, 4.5vw, 3.85rem);   /* hero headline              */
  --fs-figure: clamp(2.4rem, 5vw, 4.1rem);       /* serif numerals, HQ city    */

  /* Rhythm */
  --section-y:    clamp(4.5rem, 9vw, 8.5rem);
  --gutter:       clamp(1.25rem, 3vw, 2.5rem);
  --nav-h:        84px;

  /* Motion */
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* Bootstrap overrides */
:root {
  --bs-body-font-family: var(--font-body);
  --bs-body-color: var(--epe-ink);
  --bs-body-bg: var(--epe-bone);
  --bs-border-radius: 0;
  --bs-link-color: var(--epe-navy);
  --bs-link-hover-color: var(--epe-brass);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
* { border-radius: 0 !important; }   /* square corners, site-wide */

html { scroll-behavior: smooth; scroll-padding-top: var(--nav-h); }

body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-md);
  line-height: 1.72;
  color: var(--epe-ink);
  background: var(--epe-bone);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 300; letter-spacing: -.01em; }

::selection { background: var(--epe-navy); color: #fff; }

a { text-decoration: none; transition: color .25s var(--ease); }

:focus-visible {
  outline: 2px solid var(--epe-brass);
  outline-offset: 3px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 2000;
  background: var(--epe-navy); color: #fff; padding: .85rem 1.4rem;
  font-family: var(--font-display); font-size: var(--fs-sm); letter-spacing: .12em; text-transform: uppercase;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   3. Typography primitives
   -------------------------------------------------------------------------- */
.eyebrow {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--epe-ink-mute);
  margin: 0 0 1.35rem;
  display: flex;
  align-items: center;
  gap: .85rem;
}
.eyebrow::before {
  content: "";
  width: 34px; height: 1px;
  background: var(--epe-brass);
  flex: 0 0 34px;
}
.eyebrow-light { color: rgba(255, 255, 255, .62); }
.eyebrow-green::before { background: var(--epe-green); }

.display-hero {
  font-size: var(--fs-h1);
  font-weight: 200;
  line-height: 1.12;
  letter-spacing: -.02em;
  color: #fff;
  margin: 0 0 1.35rem;
}

.display-2-brand {
  font-size: var(--fs-h2);
  font-weight: 250;
  line-height: 1.14;
  letter-spacing: -.02em;
  color: var(--epe-navy);
  margin: 0 0 1.5rem;
}
.display-2-brand.text-white { color: #fff; }

.prose p { color: var(--epe-ink-soft); margin-bottom: 1.35rem; }
.prose p:last-child { margin-bottom: 0; }
.prose-tight p { margin-bottom: 1.1rem; }
.prose-invert p { color: rgba(255, 255, 255, .74); }

/* Section standfirst. Use only where it is the *sole* paragraph sitting opposite
   a section heading — there the larger size expresses a real hierarchy. Do not
   put it on the first of several continuous paragraphs: there is no standfirst
   relationship to express and the size change just reads as inconsistent. */
.lead-para {
  font-size: var(--fs-lead);
  line-height: 1.66;
  font-weight: 300;
  color: var(--epe-ink);
  margin-bottom: 1.35rem;
}
.section-navy .lead-para { color: rgba(255, 255, 255, .86); }

/* Runs the full width beneath the three cards. Set in two columns above the
   card breakpoint so it spreads across the page without the line length
   running past a readable measure. */
.note-para {
  font-size: var(--fs-base);
  color: var(--epe-ink-soft);
  padding-top: 1.6rem;
  border-top: 1px solid var(--epe-line);
  margin: 0;
}
@media (min-width: 992px) {
  .note-para {
    columns: 2;
    column-gap: clamp(2.5rem, 5vw, 5rem);
    orphans: 2;
    widows: 2;
  }
}

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.container-xxl { max-width: 1440px; padding-inline: var(--gutter); }

.section { padding-block: var(--section-y); position: relative; }
.section-light { background: var(--epe-bone); }
.section-tint  { background: var(--epe-tint); }
.section-navy  { background: var(--epe-navy); color: #fff; }

.section-navy::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(900px 420px at 12% -10%, rgba(192, 161, 107, .11), transparent 62%),
    radial-gradient(700px 380px at 92% 108%, rgba(10, 44, 101, .8), transparent 60%);
  pointer-events: none;
}
.section-navy > * { position: relative; z-index: 1; }

.section-head { margin-bottom: clamp(2.5rem, 4.5vw, 4rem); }

/* --------------------------------------------------------------------------
   4b. Light section carrying background artwork
   The image sits low in the frame and is washed back by a bone scrim that is
   heaviest where the copy sits, so body text keeps its contrast ratio.
   -------------------------------------------------------------------------- */
.section-media {
  position: relative;
  overflow: hidden;
  padding-bottom: clamp(9rem, 18vw, 16rem);
}
.section-media > .container-xxl { position: relative; z-index: 3; }

.section-media-img { position: absolute; inset: 0; z-index: 0; }
.section-photo {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 78%;
  opacity: .8;
  /* Fade in and out rather than butting against the section edge, which reads
     as a flat grey block. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 26%, #000 58%, #000 80%, transparent 99%);
          mask-image: linear-gradient(to bottom, transparent 26%, #000 58%, #000 80%, transparent 99%);
}
/* The SVG artwork is composed with its subject low in the frame; a photograph
   usually has it mid-frame, so it needs a different crop and a mask that opens
   up earlier and holds longer. Scoping to .is-photo means removing that class
   restores the artwork's settings automatically. */
.is-photo .section-photo {
  /* --photo-focus is the vertical crop dial when trialling images: 0% pins the
     top of the photo, 100% the bottom. The 12% default drops the subject into
     the lower half, clear of the copy. Override it inline on the wrapper —
     style="--photo-focus: 40%" — without touching this file. */
  object-position: center var(--photo-focus, 12%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 4%, #000 30%, #000 86%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 4%, #000 30%, #000 86%, transparent 100%);
}

/* Text protection over the upper part of the frame only. */
.section-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to bottom,
    rgba(244, 244, 242, .94) 0%,
    rgba(244, 244, 242, .78) 42%,
    rgba(244, 244, 242, .18) 62%,
    rgba(244, 244, 242, 0)  80%);
}

/* A photograph carries far more tonal variation than the flat artwork, and its
   subject sits higher in the frame, so the copy can end up over it. Hold the
   wash strong to the foot of the text (~62%), then drop it away quickly so the
   image still reads below. Measured worst case over the image is ~5.4:1. */
.section-media:has(.is-photo) .section-scrim {
  background: linear-gradient(to bottom,
    rgba(244, 244, 242, .96) 0%,
    rgba(244, 244, 242, .93) 45%,
    rgba(244, 244, 242, .88) 66%,
    rgba(244, 244, 242, .30) 77%,
    rgba(244, 244, 242, 0)  90%);
}

/* --------------------------------------------------------------------------
   4c. Photographic treatment

   Two separate opt-ins, so a slot can hold a photograph without being tinted:

     .is-photo    — this slot holds a photograph. Sets the navy ground behind
                    it and switches the slot to its photo framing (crop dials,
                    band ratios, mobile behaviour — see each component).
     .is-duotone  — additionally render it as a navy duotone: desaturate, then
                    blend for luminosity only so it takes its hue from the navy
                    behind. `isolation` keeps that blend inside this box.

   Use both together for imagery that must sit in the palette; use .is-photo
   alone where the photograph should read in its own colours.
   -------------------------------------------------------------------------- */
.is-photo {
  background: var(--epe-navy);
  isolation: isolate;
}
.is-duotone img {
  mix-blend-mode: luminosity;
  filter: grayscale(1) contrast(1.08) brightness(1.04);
}

/* Fallback: without blend-mode support the photo would show in full colour,
   so fall back to a plain desaturated-and-cooled treatment. */
@supports not (mix-blend-mode: luminosity) {
  .is-duotone img {
    filter: grayscale(1) contrast(1.08) sepia(.35) hue-rotate(175deg) saturate(2.2) brightness(.92);
  }
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  --bs-btn-border-radius: 0;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 1.05rem 2.1rem;
  border: 1px solid transparent;
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.btn + .btn { margin-left: .75rem; }

.btn-brass { background: var(--epe-brass); color: var(--epe-navy); border-color: var(--epe-brass); }
.btn-brass:hover, .btn-brass:focus-visible { background: var(--epe-brass-light); border-color: var(--epe-brass-light); color: var(--epe-navy); }

.btn-ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .38); }
.btn-ghost:hover, .btn-ghost:focus-visible { background: #fff; color: var(--epe-navy); border-color: #fff; }

.btn-navy { background: var(--epe-navy); color: #fff; border-color: var(--epe-navy); }
.btn-navy:hover, .btn-navy:focus-visible { background: var(--epe-brass); border-color: var(--epe-brass); color: var(--epe-navy); }

/* The navbar has no button variant — every item there is a plain .nav-link. */

/* --------------------------------------------------------------------------
   6. Header / navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 1030;
  transition: background-color .4s var(--ease), box-shadow .4s var(--ease), border-color .4s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  background: rgba(2, 23, 59, .96);
  border-bottom-color: var(--epe-line-dark);
}
/* Only above the navbar's expand point. Below it the offcanvas is a
   position:fixed panel nested inside this header, and backdrop-filter would
   make the header its containing block — see .menu-open below. The header is
   opaque at those widths anyway, so the frosting has nothing to show through. */
@media (min-width: 1200px) {
  .site-header.is-scrolled { backdrop-filter: saturate(140%) blur(10px); }
}

/* While the mobile menu is open the header must not establish a containing
   block for it. `transform` and `backdrop-filter` both do, and the offcanvas
   then sizes to the 72px header instead of the viewport — which left about one
   menu item reachable after any scroll. Transition is killed too: an animating
   transform still counts, so letting it ease back to none would keep the bug
   alive for the length of the transition. */
.site-header.menu-open {
  transform: none !important;
  backdrop-filter: none !important;
  transition: none;
}
.site-header.is-hidden { transform: translateY(-100%); }
.site-header { transition: transform .45s var(--ease), background-color .4s var(--ease), border-color .4s var(--ease); }

.navbar {
  padding: 0;
  /* Bootstrap's navbar defaults are dark-on-light; this navbar is always on navy. */
  --bs-navbar-color: rgba(255, 255, 255, .78);
  --bs-navbar-hover-color: #fff;
  --bs-navbar-active-color: #fff;
  --bs-navbar-brand-color: #fff;
  --bs-navbar-brand-hover-color: #fff;
}
.navbar .container-xxl { min-height: var(--nav-h); align-items: center; }

.navbar-brand { display: flex; align-items: center; gap: .95rem; padding: 0; margin: 0; }
.brand-mark {
  width: auto; height: 44px;
  object-fit: contain;
  transition: height .35s var(--ease);
}
.is-scrolled .brand-mark { height: 38px; }

.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name {
  font-family: var(--font-display);
  font-size: var(--fs-md); font-weight: 300; letter-spacing: .09em;
  text-transform: uppercase; color: #fff;
}
.brand-sub {
  font-family: var(--font-display);
  font-size: var(--fs-2xs); font-weight: 300; letter-spacing: .24em;
  text-transform: uppercase; color: var(--epe-brass);
  margin-top: .22rem;
}

.navbar-nav { gap: 0; align-items: center; }
.nav-link {
  font-family: var(--font-display);
  font-size: var(--fs-base); font-weight: 300; letter-spacing: .02em;
  line-height: 1.2;                      /* not the 1.72 body value, which bloats the box */
  color: rgba(255, 255, 255, .78);
  padding: .6rem .85rem;
  position: relative;
}
.nav-link::after {
  content: "";
  position: absolute; left: .85rem; right: .85rem; bottom: .05rem;
  height: 1px; background: var(--epe-brass);
  transform: scaleX(0); transform-origin: left;
  transition: transform .32s var(--ease);
}
.navbar-nav .nav-link:hover,
.navbar-nav .nav-link:focus-visible,
.navbar-nav .nav-link.active { color: #fff; }
.nav-link:hover::after, .nav-link.active::after { transform: scaleX(1); }


/* Toggler */
.navbar-toggler { border: 0; padding: .5rem; box-shadow: none !important; }
.toggler-bars { display: block; width: 26px; }
.toggler-bars span {
  display: block; height: 1px; background: #fff; margin: 6px 0;
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}

/* Offcanvas (mobile only).
   Bootstrap keeps the .offcanvas wrapper in the DOM at every breakpoint — at
   >=xl it simply becomes a static container. These rules must therefore be
   confined to the collapsed range, or they outrank the desktop .nav-link
   styles by specificity and wreck the bar. */
@media (max-width: 1199.98px) {
  .offcanvas {
    background: var(--epe-navy);
    color: #fff;
    border-left: 1px solid var(--epe-line-dark);
    width: min(88vw, 380px);
  }
  .offcanvas-header { padding: 1.6rem var(--gutter) .8rem; }
  .offcanvas-header .eyebrow { margin-bottom: 0; }
  .offcanvas-body { padding: 1rem var(--gutter) 2.5rem; }
  .offcanvas .btn-close { filter: invert(1) grayscale(1); opacity: .7; }
  .offcanvas .nav-link {
    font-size: var(--fs-lg); padding: .95rem 0;
    border-bottom: 1px solid var(--epe-line-dark);
  }
  .offcanvas .nav-link::after { display: none; }
  .offcanvas .navbar-nav { gap: 0; align-items: stretch; }
}

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: calc(var(--nav-h) + 4rem);
  background: var(--epe-navy);
  overflow: hidden;
  isolation: isolate;
}

.hero-canvas { position: absolute; inset: 0; z-index: 0; }

/* Photograph / illustration layer. Swapping the <img> src is the only change
   needed to drop in real photography. */
.hero-media { position: absolute; inset: 0; z-index: 1; overflow: hidden; }
.hero-photo {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 62%;
  opacity: .92;
}
/* A photograph carries its own tonal range, so it goes in at full strength and
   takes its crop from the focus dial rather than the artwork's fixed 62%.

   When a photo's aspect nearly matches the hero there is no overflow left to
   pan into, so object-position alone cannot move a subject out from behind the
   headline. --photo-zoom scales the image up to create that room and
   --photo-origin picks the anchor: an origin left of centre pushes mid-frame
   subjects rightward, into the clear side of the layout. Zooming costs
   sharpness, so keep it at 1 unless the framing needs it. */
.hero-media.is-photo .hero-photo {
  object-position: center var(--photo-focus, 50%);
  opacity: 1;
  transform: scale(var(--photo-zoom, 1));
  transform-origin: var(--photo-origin, center);
}

/* Legibility scrim: dark at the lower-left where the copy sits, clearing
   towards the upper right so the skyline still reads. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(100deg, rgba(1, 12, 32, .93) 0%, rgba(2, 20, 50, .78) 34%, rgba(2, 23, 59, .26) 66%, rgba(2, 23, 59, .06) 100%),
    linear-gradient(to top, rgba(1, 12, 32, .72) 0%, rgba(1, 15, 40, .18) 26%, transparent 52%);
}

/* The vector hero is dark along its top edge, so the transparent navbar reads
   against it. A photograph often has bright sky up there, which washes the nav
   links out — add a short gradient behind the bar without darkening the frame. */
.hero:has(.is-photo) .hero-scrim {
  background:
    linear-gradient(to bottom, rgba(1, 12, 32, .82) 0, rgba(1, 12, 32, .44) 90px, rgba(1, 12, 32, 0) 210px),
    linear-gradient(100deg, rgba(1, 12, 32, .90) 0%, rgba(2, 20, 50, .74) 34%, rgba(2, 23, 59, .30) 66%, rgba(2, 23, 59, .12) 100%),
    linear-gradient(to top, rgba(1, 12, 32, .74) 0%, rgba(1, 15, 40, .20) 26%, transparent 52%);
}

/* An untinted photograph keeps its bright passages — sky, water, the Jet d'Eau —
   so the diagonal wash has to work harder behind the headline. Measured: without
   this the headline falls to 2.69:1 (needs 3) and the standfirst to 3.12:1
   (needs 4.5). Scoped to :not(.is-duotone) so putting the duotone back also
   restores the lighter wash — the revert stays a single class. */
.hero:has(.is-photo:not(.is-duotone)) .hero-scrim {
  background:
    linear-gradient(to bottom, rgba(1, 12, 32, .82) 0, rgba(1, 12, 32, .44) 90px, rgba(1, 12, 32, 0) 210px),
    linear-gradient(100deg, rgba(1, 12, 32, .94) 0%, rgba(2, 20, 50, .86) 34%, rgba(2, 23, 59, .58) 66%, rgba(2, 23, 59, .20) 100%),
    linear-gradient(to top, rgba(1, 12, 32, .74) 0%, rgba(1, 15, 40, .20) 26%, transparent 52%);
}

.hero-lines { position: absolute; inset: 0; z-index: 3; }
.hero-canvas::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(1200px 700px at 78% 8%,  rgba(10, 44, 101, .95), transparent 60%),
    radial-gradient(900px 620px at 8% 96%,   rgba(192, 161, 107, .16), transparent 62%),
    linear-gradient(160deg, var(--epe-navy-900) 0%, var(--epe-navy) 55%, #041c46 100%);
}
.hero-canvas::after {
  /* fine engraved texture */
  content: "";
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.028) 0 1px, transparent 1px 64px);
  mask-image: linear-gradient(to bottom, transparent, #000 35%, #000 75%, transparent);
}
.flowlines {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: .55;
}
.flowlines path {
  stroke-dasharray: 2400;
  stroke-dashoffset: 2400;
  animation: draw 3.4s var(--ease) forwards;
}
.flowlines path:nth-child(2) { animation-delay: .18s; }
.flowlines path:nth-child(3) { animation-delay: .36s; }
.flowlines path:nth-child(4) { animation-delay: .54s; }
.flowlines path:nth-child(5) { animation-delay: .72s; }
@keyframes draw { to { stroke-dashoffset: 0; } }

.hero-inner { position: relative; z-index: 4; padding-bottom: clamp(3.5rem, 7vw, 6rem); }

.hero-standfirst {
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: 300;
  letter-spacing: .1em;
  color: var(--epe-brass-light);
  margin: 0 0 1.9rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(255, 255, 255, .18);
  display: inline-block;
}

.hero-lead {
  font-size: var(--fs-lead);
  font-weight: 300;
  line-height: 1.7;
  color: rgba(255, 255, 255, .74);
  max-width: 62ch;
  margin: 0 0 2.6rem;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: .9rem; }
.hero-actions .btn + .btn { margin-left: 0; }

.hero-rail {
  position: relative; z-index: 4;
  border-top: 1px solid var(--epe-line-dark);
  background: rgba(1, 15, 40, .62);
  backdrop-filter: blur(2px);
}
.hero-tags {
  display: flex; flex-wrap: wrap;
  list-style: none; margin: 0; padding: 1.35rem 0;
  gap: clamp(1.5rem, 5vw, 4.5rem);
}
.hero-tags li {
  font-family: var(--font-display);
  font-size: var(--fs-xs); font-weight: 300;
  letter-spacing: .2em; text-transform: uppercase;
  color: rgba(255, 255, 255, .58);
  display: flex; align-items: center; gap: .8rem;
}
.hero-tags li::before {
  content: ""; width: 5px; height: 5px;
  background: var(--epe-brass);
}

/* --------------------------------------------------------------------------
   8. Stat band
   -------------------------------------------------------------------------- */
.stat-band {
  background: var(--epe-navy-900);
  color: #fff;
  padding-block: clamp(3rem, 5vw, 4.5rem);
}
.stat-row { border-top: 1px solid var(--epe-line-dark); }
.stat-row > [class*="col-"] { border-bottom: 1px solid var(--epe-line-dark); }
@media (min-width: 992px) {
  .stat-row > [class*="col-"] + [class*="col-"] { border-left: 1px solid var(--epe-line-dark); }
  .stat-row > [class*="col-"] { border-bottom: 0; }
}

.stat { padding: 2rem 1.5rem 2rem 0; }
@media (min-width: 992px) { .stat { padding: 2.2rem 1.5rem 1rem 2rem; } .stat-row > [class*="col-"]:first-child .stat { padding-left: 0; } }

.stat-figure {
  display: block;
  font-family: var(--font-serif);
  font-size: var(--fs-figure);
  font-weight: 300;
  line-height: 1;
  color: #fff;
  letter-spacing: -.01em;
}
.stat-figure-text { font-family: var(--font-display); font-weight: 200; letter-spacing: .04em; }
.stat-suffix { color: var(--epe-brass); }
.stat-label {
  display: block;
  margin-top: .95rem;
  font-family: var(--font-display);
  font-size: var(--fs-sm); font-weight: 300;
  letter-spacing: .12em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  max-width: 20ch;
}

/* --------------------------------------------------------------------------
   9. Plate (illustrative panel)
   -------------------------------------------------------------------------- */
/* Contained media carries a hairline, matching .map-frame in the contact
   panel; full-bleed media (hero, section backgrounds) does not. */
.plate {
  margin: 0; height: 100%; min-height: 340px;
  overflow: hidden;
  position: relative;
  background: var(--epe-navy);
  border: 1px solid var(--epe-line);
}
.plate-art {
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  object-position: center var(--photo-focus, 50%);
}

/* --------------------------------------------------------------------------
   10. Mission pull-quote
   -------------------------------------------------------------------------- */
.pull-quote {
  font-family: var(--font-serif);
  font-size: var(--fs-quote);
  font-weight: 300;
  line-height: 1.42;
  color: #fff;
  margin: 0;
  letter-spacing: -.005em;
}

/* --------------------------------------------------------------------------
   11. Values
   -------------------------------------------------------------------------- */
.value-list {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--epe-line);
}
.value {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr);
  gap: 0 1.5rem;
  padding: 2.1rem 0;
  border-bottom: 1px solid var(--epe-line);
  transition: background-color .35s var(--ease), padding-left .35s var(--ease);
}
.value:hover { background: rgba(255, 255, 255, .55); padding-left: 1rem; }

.value-num {
  font-family: var(--font-display);
  font-size: var(--fs-sm); font-weight: 400; letter-spacing: .18em;
  color: var(--epe-brass-ink);
  padding-top: .45rem;
}
.value-title {
  font-size: var(--fs-title);
  font-weight: 300;
  color: var(--epe-navy);
  margin: 0 0 .35rem;
}
.value-body { margin: 0; color: var(--epe-ink-soft); max-width: 78ch; }

@media (min-width: 992px) {
  .value { grid-template-columns: 90px 300px minmax(0, 1fr); align-items: baseline; }
  .value-title { margin-bottom: 0; }
}

/* --------------------------------------------------------------------------
   12. Trade cards
   -------------------------------------------------------------------------- */
/* Banner sits directly above the grid, at the same width, so its three zones
   register with the three trade cards. */
.trade-banner {
  margin: 0 0 clamp(2.5rem, 4.5vw, 3.75rem);
  background: var(--epe-navy);
  overflow: hidden;
}
.trade-banner-img { display: block; width: 100%; height: auto; }

/* The SVG banner is 3.75:1 and sets its own height. A photograph is usually
   nearer 16:9, which at full container width would tower over the cards, so
   the figure takes a fixed band ratio and the photo is cropped into it. */
.trade-banner.is-photo { aspect-ratio: 2.8 / 1; }
.trade-banner.is-photo .trade-banner-img {
  height: 100%;
  object-fit: cover;
  object-position: center var(--photo-focus, 56%);
}

/* --- carousel variant ------------------------------------------------------
   The slide wrapper must inherit the band's height. Each item also carries the
   navy ground: it backs the frame while an image loads, and it is required if
   .is-duotone is ever added here — Bootstrap transforms items while sliding,
   which creates a stacking context, so the luminosity blend would composite
   against the item rather than the outer box and drop out mid-slide. */
.trade-banner .carousel-inner,
.trade-banner .carousel-item { height: 100%; }
.trade-banner .carousel-item { background: var(--epe-navy); }

.trade-banner .carousel-control-prev,
.trade-banner .carousel-control-next {
  width: 9%;
  opacity: .55;
  transition: opacity .3s var(--ease);
}
.trade-banner .carousel-control-prev:hover,
.trade-banner .carousel-control-next:hover,
.trade-banner .carousel-control-prev:focus-visible,
.trade-banner .carousel-control-next:focus-visible { opacity: 1; }

.trade-banner .carousel-indicators {
  margin: 0 0 1.15rem;
  gap: .5rem;
}
.trade-banner .carousel-indicators [data-bs-target] {
  width: 34px; height: 2px;
  margin: 0; border: 0;
  background-color: rgba(255, 255, 255, .5);
  opacity: 1;
  transition: background-color .3s var(--ease);
}
.trade-banner .carousel-indicators .active { background-color: var(--epe-brass); }

.trade-grid { border-top: 1px solid var(--epe-line); }

.trade-card {
  display: flex;
  flex-direction: column;
  padding: clamp(2rem, 3.2vw, 3rem) clamp(1.5rem, 2.6vw, 2.5rem) clamp(2.2rem, 3.2vw, 3rem) 0;
  border-bottom: 1px solid var(--epe-line);
  transition: background-color .4s var(--ease);
}

.trade-icon { color: var(--epe-brass-ink); margin-bottom: 1.75rem; }
.trade-icon svg { width: 46px; height: 46px; display: block; }

.trade-title {
  font-size: var(--fs-title);
  font-weight: 300;
  color: var(--epe-navy);
  margin: 0 0 .9rem;
}
/* max-width only bites in the stacked layout below 1200px, where a card spans
   the full container; the three-column tracks are well under it. */
.trade-body { color: var(--epe-ink-soft); margin: 0 0 1.6rem; max-width: 74ch; }

.chip-list {
  display: flex; flex-wrap: wrap; gap: .45rem;
  align-content: flex-start;
  list-style: none; padding: 0; margin: 0;
}
/* Tracking and padding are kept tight deliberately: at the previous .14em /
   .8rem the longest set ("Base metals · Coal · Agricultural bulks") cleared its
   column by only ~7px, so a slightly wider font metric or a fallback face while
   the webfont loaded pushed the last chip onto a second line. */
.chip-list li {
  font-family: var(--font-display);
  font-size: var(--fs-2xs); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap;
  color: var(--epe-ink-soft);
  border: 1px solid var(--epe-line);
  padding: .44rem .7rem;
  background: rgba(255, 255, 255, .6);
}

/* Three-column layout. Declared after the element rules above so nothing here
   is overridden by a later same-specificity declaration.

   Goes side-by-side at 1200px, not 992px: between the two the columns are only
   ~250px and the product chips are forced onto a second row. Full-width stacked
   cards below that give them room, and it matches the navbar's breakpoint. */
@media (min-width: 1200px) {
  .trade-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
  .trade-card { border-bottom: 0; padding-right: clamp(1.5rem, 2.6vw, 3rem); }
  .trade-card + .trade-card {
    border-left: 1px solid var(--epe-line);
    padding-left: clamp(1.5rem, 2.6vw, 3rem);
  }

  /* Subgrid gives every card the same four row tracks — icon, title, body,
     chips — so each element lines up across all three columns. Pushing the
     chips to the foot instead only aligns the card feet, which breaks as soon
     as one card's chips wrap onto a second row. */
  @supports (grid-template-rows: subgrid) {
    .trade-grid { grid-template-rows: auto auto 1fr auto; }
    .trade-card {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
    }
  }

  /* Fallback where subgrid is unavailable: bottom-align instead. */
  @supports not (grid-template-rows: subgrid) {
    .chip-list { margin-top: auto; }
  }
}

/* --------------------------------------------------------------------------
   13. Steps (how we work)
   -------------------------------------------------------------------------- */
.step-grid { border-top: 1px solid var(--epe-line-dark); }
.step {
  height: 100%;
  padding: 2.4rem 1.75rem 2.4rem 0;
  border-bottom: 1px solid var(--epe-line-dark);
}
@media (min-width: 992px) {
  .step { border-bottom: 0; padding: 2.6rem 2rem 1rem 0; }
  .step-grid > [class*="col-"] + [class*="col-"] .step { border-left: 1px solid var(--epe-line-dark); padding-left: 2rem; }
}
.step-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-sm); letter-spacing: .2em; font-weight: 300;
  color: var(--epe-brass);
  margin-bottom: 1.5rem;
}
.step-title { font-size: var(--fs-lg); font-weight: 300; color: #fff; margin: 0 0 .7rem; }
.step-body { color: rgba(255, 255, 255, .66); font-size: var(--fs-base); margin: 0; }

/* --------------------------------------------------------------------------
   14. Green energy
   -------------------------------------------------------------------------- */
.green-section { background: linear-gradient(180deg, var(--epe-bone) 0%, #eef1ee 100%); }

.rule-green { width: 64px; height: 2px; background: var(--epe-green); margin: 0 0 1.75rem; }

.feature-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--epe-line); }
.feature-list li {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 1.25rem;
  padding: 1.9rem 0;
  border-bottom: 1px solid var(--epe-line);
}
.feature-list p { margin: 0; color: var(--epe-ink-soft); font-size: var(--fs-md); }
.feature-list strong { color: var(--epe-navy); font-weight: 500; }
.feature-mark {
  width: 10px; height: 10px;
  margin-top: .6rem;
  border: 1px solid var(--epe-green);
  position: relative;
}
.feature-mark::after {
  content: ""; position: absolute; inset: 2px;
  background: var(--epe-green);
}

/* --------------------------------------------------------------------------
   15. Compliance
   -------------------------------------------------------------------------- */
.compliance-card {
  height: 100%;
  background: var(--epe-paper);
  border: 1px solid var(--epe-line);
  border-left: 2px solid var(--epe-navy);
  padding: clamp(1.6rem, 2.4vw, 2.2rem);
  transition: border-left-color .35s var(--ease), transform .35s var(--ease);
}
.compliance-card:hover { border-left-color: var(--epe-brass); transform: translateY(-3px); }
.compliance-card h3 {
  font-size: var(--fs-lg); font-weight: 400; color: var(--epe-navy);
  margin: 0 0 .65rem;
}
.compliance-card p { margin: 0; color: var(--epe-ink-soft); font-size: var(--fs-base); }

/* --------------------------------------------------------------------------
   16. Presence / HQ card
   -------------------------------------------------------------------------- */
.hq-card {
  border: 1px solid var(--epe-line-dark);
  background: rgba(255, 255, 255, .035);
  padding: clamp(2rem, 3.4vw, 3rem);
}
.hq-city {
  font-family: var(--font-serif);
  font-size: var(--fs-figure);
  font-weight: 300; line-height: 1;
  color: #fff; margin: 0 0 1.4rem;
}
.hq-address {
  font-style: normal;
  color: rgba(255, 255, 255, .74);
  margin: 0 0 2rem;
  line-height: 1.85;
}
.hq-meta { display: flex; flex-wrap: wrap; gap: 2.5rem; margin: 0; padding-top: 1.6rem; border-top: 1px solid var(--epe-line-dark); }
.hq-meta dt {
  font-family: var(--font-display);
  font-size: var(--fs-2xs); font-weight: 300; letter-spacing: .18em;
  text-transform: uppercase; color: var(--epe-brass);
  margin-bottom: .4rem;
}
.hq-meta dd { margin: 0; color: rgba(255, 255, 255, .8); font-size: var(--fs-base); }

/* --------------------------------------------------------------------------
   17. Careers
   -------------------------------------------------------------------------- */
.careers .prose { max-width: 62ch; }

/* --------------------------------------------------------------------------
   18. Contact
   -------------------------------------------------------------------------- */
.contact-company {
  font-family: var(--font-display);
  font-size: var(--fs-lg); font-weight: 400; letter-spacing: .02em;
  color: var(--epe-navy);
  margin: 0 0 1.75rem;
}
.contact-row {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 1rem;
  padding: 1.1rem 0;
  border-top: 1px solid var(--epe-line);
}
.contact-key {
  font-family: var(--font-display);
  font-size: var(--fs-xs); font-weight: 300; letter-spacing: .18em;
  text-transform: uppercase; color: var(--epe-ink-mute);
  padding-top: .2rem;
}
.contact-val { font-style: normal; margin: 0; color: var(--epe-ink); }
.contact-val a { color: var(--epe-navy); border-bottom: 1px solid var(--epe-line); }
.contact-val a:hover { color: var(--epe-brass); border-bottom-color: var(--epe-brass); }

.map-frame {
  margin-top: 2.25rem;
  border: 1px solid var(--epe-line);
  aspect-ratio: 16 / 10;
  background: var(--epe-tint);
}
/* Left in full colour: the map is wayfinding, not decoration, and the green of
   the parks and the blue of the lake are what make it read as Geneva at a
   glance. It was desaturated when the site's imagery was a navy duotone; now
   that the photography runs in its own colours, so does this. */
.map-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* Form */
.form-label {
  font-family: var(--font-display);
  font-size: var(--fs-xs); font-weight: 300; letter-spacing: .16em;
  text-transform: uppercase; color: var(--epe-ink-mute);
  margin-bottom: .55rem;
}
.form-label span { color: var(--epe-brass-ink); }

.form-control, .form-select {
  border: 1px solid var(--epe-line);
  background: var(--epe-paper);
  padding: .9rem 1rem;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  color: var(--epe-ink);
  transition: border-color .28s var(--ease), box-shadow .28s var(--ease);
}
.form-control:focus, .form-select:focus {
  border-color: var(--epe-navy);
  box-shadow: 0 0 0 3px rgba(2, 23, 59, .08);
  background: var(--epe-paper);
}
.form-control::placeholder { color: var(--epe-ink-mute); }
.was-validated .form-control:invalid, .form-control.is-invalid,
.was-validated .form-check-input:invalid { border-color: #a33; }

.form-check-input {
  border: 1px solid var(--epe-line);
  width: 1.05em; height: 1.05em;
  margin-top: .35em;
}
.form-check-input:checked { background-color: var(--epe-navy); border-color: var(--epe-navy); }
.form-check-input:focus { box-shadow: 0 0 0 3px rgba(2, 23, 59, .08); border-color: var(--epe-navy); }
.form-check-label { font-size: var(--fs-base); color: var(--epe-ink-soft); padding-left: .35rem; }

.invalid-feedback { font-size: var(--fs-sm); }

.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-status {
  margin: 1.1rem 0 0;
  font-size: var(--fs-base);
  color: var(--epe-green);
  min-height: 1.4rem;
}
.form-status.is-error { color: #a33; }

/* --------------------------------------------------------------------------
   19. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--epe-navy-900);
  color: rgba(255, 255, 255, .7);
  padding-top: clamp(3.5rem, 6vw, 5.5rem);
  font-size: var(--fs-base);
}
.footer-main { padding-bottom: clamp(2.5rem, 4vw, 3.5rem); }
.footer-logo { width: 200px; height: auto; margin-bottom: 1.6rem; }
.footer-blurb { color: rgba(255, 255, 255, .58); max-width: 34ch; margin: 0; }

.footer-nav { list-style: none; margin: 0; padding: 0; }
.footer-nav li { margin-bottom: .7rem; }
.footer-nav a { color: rgba(255, 255, 255, .7); }
.footer-nav a:hover { color: var(--epe-brass); }

.footer-address { font-style: normal; color: rgba(255, 255, 255, .7); line-height: 1.95; margin: 0; }
.footer-address a { color: rgba(255, 255, 255, .7); }
.footer-address a:hover { color: var(--epe-brass); }

.footer-bar {
  border-top: 1px solid var(--epe-line-dark);
  padding-block: 1.75rem 2.25rem;
  display: flex; flex-wrap: wrap; gap: 1rem 2.5rem;
  align-items: baseline; justify-content: space-between;
}
.footer-copy { margin: 0; font-size: var(--fs-sm); color: rgba(255, 255, 255, .55); flex: 0 0 auto; }
.footer-legal {
  margin: 0; font-size: var(--fs-xs); color: rgba(255, 255, 255, .55);
  max-width: 68ch; line-height: 1.7;
  flex: 1 1 360px;
}

/* --------------------------------------------------------------------------
   20. Back to top — a footer link rather than a floating button, which would
   sit over body copy at viewports between the container width and 1440px.
   -------------------------------------------------------------------------- */
.to-top {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-display);
  font-size: var(--fs-xs); font-weight: 300;
  letter-spacing: .18em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  white-space: nowrap;
}
.to-top:hover { color: var(--epe-brass); }
.to-top svg { width: 14px; height: 14px; }

/* --------------------------------------------------------------------------
   21. Reveal animation
   -------------------------------------------------------------------------- */
/* Only hidden when JS is running (the `js` class is set in <head>), so a
   script failure can never leave the page blank. */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms);
}
.js .reveal.is-in { opacity: 1; transform: none; }
[data-reveal-delay="1"] { --d: 1; }
[data-reveal-delay="2"] { --d: 2; }
[data-reveal-delay="3"] { --d: 3; }
[data-reveal-delay="4"] { --d: 4; }

/* --------------------------------------------------------------------------
   22. Responsive refinements
   -------------------------------------------------------------------------- */
/* Between the lg column breakpoint and the navbar's xl expand point the bar has
   room to spare; trim the link padding so it never crowds the brand. */
@media (min-width: 1200px) and (max-width: 1439.98px) {
  .nav-link { padding-inline: .62rem; font-size: var(--fs-sm); }
  .nav-link::after { left: .62rem; right: .62rem; }
}

@media (max-width: 1199.98px) {
  .site-header { background: rgba(2, 23, 59, .96); border-bottom-color: var(--epe-line-dark); }
}

@media (max-width: 991.98px) {
  :root { --nav-h: 72px; }
  .hero { min-height: auto; padding-top: calc(var(--nav-h) + 3.5rem); }
  .hero-inner { padding-bottom: 3.25rem; }
  .brand-sub { display: none; }
  /* Two columns but three children: without explicit placement the body text
     auto-flows into column 1 and is squeezed into the number's 54px track.
     Pin the numeral down the left and stack title over body beside it. */
  .value { grid-template-columns: 54px minmax(0, 1fr); }
  .value-num { grid-row: 1 / span 2; }
  .value-title,
  .value-body { grid-column: 2; }
  .contact-row { grid-template-columns: 1fr; gap: .35rem; }
  .footer-bar { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 575.98px) {
  .btn { width: 100%; text-align: center; }
  .hero-actions { flex-direction: column; }
  .brand-name { font-size: var(--fs-base); }
  /* --fs-figure already floors at 2.4rem on small screens, so the old override
     here was doing nothing. */
  /* The rail stacks at this width — the wide inline gap becomes dead space. */
  .hero-tags { gap: .7rem; padding-block: 1.15rem; }
}

/* A 21:9 image cropped into a tall phone viewport keeps only ~20% of its
   width; bias the crop so the Jet d'Eau and cathedral stay in frame. */
@media (max-width: 767.98px) {
  .hero-photo { object-position: 67% 58%; opacity: .8; }
}

/* Below the two-column breakpoint the copy fills the section, leaving no room
   to lay an image behind it. Give the artwork its own band under the text and
   show the vessel whole, rather than cropping it to an unreadable sliver. */
@media (max-width: 991.98px) {
  .section-media { padding-bottom: calc(min(100vw, 640px) * .4583 + 3rem); }
  .section-media-img {
    top: auto; bottom: 0;
    left: 50%; transform: translateX(-50%);
    width: min(100%, 640px);
    height: auto;
    aspect-ratio: 24 / 11;
  }
  .section-photo {
    object-fit: contain;
    opacity: .85;
    -webkit-mask-image: linear-gradient(to bottom, transparent 4%, #000 34%, #000 88%, transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 4%, #000 34%, #000 88%, transparent 100%);
  }
  /* `contain` suits the wide vector artwork, which must be seen end to end. A
     photograph is any aspect and would letterbox against the navy, so fill the
     band and let the focus dial pick the crop. */
  .is-photo .section-photo { object-fit: cover; }
  .section-scrim { display: none; }
}

/* --------------------------------------------------------------------------
   23. Motion & print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .flowlines path { stroke-dashoffset: 0; }
}

@media print {
  .site-header, .to-top, .map-frame, .contact-form, .hero-canvas { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 1.5rem; }
  .section-navy, .stat-band, .site-footer { background: #fff !important; color: #000 !important; }
  .section-navy *, .stat-band *, .site-footer * { color: #000 !important; }
}
