/* ===========================================================
   Mecantek Automation — design system

   Direction: white page, drafting-sheet structure. The frame
   sequence was shot on a seamless backdrop that has been lifted
   to pure white, so the part appears to float directly on the
   page instead of sitting inside a video box. Everything else
   stays out of its way: navy type, hairline rules, lots of air.

   Dark is spent in exactly one place — the footer.
=========================================================== */
:root {
  /* --- color --- */
  --paper: #ffffff;
  --bone: #f6f7f9;        /* section tint, barely there        */
  --ink: #0e1a24;         /* headings                          */
  --navy: #113c5f;        /* brand — 11.5:1 on paper           */
  --navy-600: #2c5c82;    /* mono labels — 6.6:1 on paper      */
  --navy-900: #0a2436;    /* footer ground                     */
  --steel: #4a6478;       /* body copy — 6.2:1 on paper        */
  --steel-200: #ccd8e0;
  /* Accent sampled from the roller in the sequence itself, then
     deepened until it holds on white (5.2:1). Used for the logo
     panel and small marks — never for long-form copy. */
  --accent: #2e6fb0;
  --accent-deep: #17497f;
  --rule: rgba(17, 60, 95, 0.12);
  --rule-dark: rgba(255, 255, 255, 0.14);

  /* --- type --- */
  --font-display: "Archivo", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Sized to the sequence's side column, not the full viewport —
     the headline shares the stage with the part. */
  --fs-hero: clamp(1.8rem, 2.9vw, 3rem);
  --fs-h2: clamp(2rem, 4vw, 3.25rem);
  --fs-h3: clamp(1.1rem, 1.5vw, 1.35rem);
  --fs-lead: clamp(1.05rem, 1.3vw, 1.2rem);
  --fs-body: 1rem;
  --fs-small: 0.875rem;
  --fs-mono: 0.6875rem;

  /* --- layout --- */
  --max-w: 1280px;
  --gutter: clamp(1.5rem, 5vw, 4.5rem);
  --sp-section: clamp(5.5rem, 11vw, 9.5rem);
  --sp-block: clamp(2.5rem, 5vw, 4.5rem);
  --radius: 14px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- reset ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, canvas { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; cursor: pointer; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.0;
  letter-spacing: -0.03em;
}
h3 { line-height: 1.15; letter-spacing: -0.02em; }

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

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

/* ---------- primitives ---------- */
.wrap { max-width: var(--max-w); margin-inline: auto; padding-inline: var(--gutter); }

.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy-600);
}

.lead { font-size: var(--fs-lead); line-height: 1.5; color: var(--steel); max-width: 46ch; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.8rem 1.5rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: var(--fs-small);
  letter-spacing: -0.01em;
  border: 1px solid transparent;
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease),
              transform 0.3s var(--ease);
}
.btn--primary { background: var(--navy); color: var(--paper); }
.btn--primary:hover { background: var(--navy-600); transform: translateY(-1px); }
.btn--ghost { border-color: var(--rule); color: var(--navy); }
.btn--ghost:hover { border-color: var(--navy-600); background: rgba(17, 60, 95, 0.04); }

.s-head { max-width: 54ch; }
.s-head h2 { font-size: var(--fs-h2); margin-top: 1.1rem; }
.s-head .lead { margin-top: 1.4rem; }

/* ===========================================================
   Landing — the way in

   The same saturated ground the sequence resolves to, reused as
   the front door. Arriving on /outillage/ therefore lands on a
   page that already ends on this exact panel, which is what makes
   the two feel like one site rather than two.
=========================================================== */
.on-landing { background: var(--navy-900); }

.landing {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(2rem, 5vh, 3.5rem);
  padding: clamp(2rem, 6vh, 4rem) var(--gutter);
  background: linear-gradient(150deg, var(--accent-deep) 0%, var(--navy-900) 78%);
  color: var(--paper);
}

.landing__inner {
  width: 100%;
  max-width: var(--max-w);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
}
.landing__inner--solo { grid-template-columns: 1fr; justify-items: center; gap: clamp(2rem, 5vh, 3rem); }

.landing__brand {
  width: clamp(200px, 24vw, 340px);
  height: auto;
  filter: brightness(0) invert(1);
  /* Named so browsers that support cross-document view transitions
     carry the lockup across to the next page instead of cutting. */
  view-transition-name: brand-lockup;
}

/* --- the two doors --- */
.landing__door {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.55rem;
  max-width: 22rem;
  padding: 1.5rem 1.6rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.035);
  transition: border-color 0.35s var(--ease), background-color 0.35s var(--ease),
              transform 0.35s var(--ease);
}
.landing__door:hover {
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.08);
  transform: translateY(-3px);
}
.landing__door .eyebrow { color: var(--steel-200); opacity: 0.75; }
/* Left door sits above the logo's baseline, right door below, so the
   pair follows the rising arrow in the mark instead of fighting it. */
.landing__door--left { justify-self: end; margin-bottom: clamp(1rem, 6vh, 4rem); }
.landing__door--right { justify-self: start; margin-top: clamp(1rem, 6vh, 4rem); }

.landing__door-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.15rem, 1.7vw, 1.5rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
}
.landing__door-note { font-size: var(--fs-small); color: var(--steel-200); }
.landing__door-go {
  margin-top: 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.landing__arrow { transition: transform 0.35s var(--ease); }
.landing__door:hover .landing__arrow { transform: translateX(4px); }

.landing__place {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--steel-200);
  opacity: 0.6;
}

/* --- placeholder page --- */
.landing__soon { max-width: 44ch; text-align: center; }
.landing__soon h1 { font-size: clamp(1.6rem, 3vw, 2.4rem); margin: 1rem 0 1rem; }
.landing__soon p { color: var(--steel-200); }
.landing__soon-actions {
  margin-top: 2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  align-items: center;
  justify-content: center;
}
.btn--light { background: var(--paper); color: var(--navy); }
.btn--light:hover { background: var(--steel-200); transform: translateY(-1px); }
.landing__back {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-200);
  opacity: 0.8;
}
.landing__back:hover { opacity: 1; }

@media (max-width: 900px) {
  .landing__inner { grid-template-columns: 1fr; justify-items: center; }
  .landing__door { max-width: 30rem; width: 100%; }
  .landing__door--left,
  .landing__door--right { justify-self: stretch; margin: 0; }
  .landing__brand { width: clamp(180px, 46vw, 260px); order: -1; }
}

/* ===========================================================
   Page transitions

   Cross-document view transitions where supported; everywhere else
   the load fade below still makes the move feel deliberate.
=========================================================== */
@view-transition { navigation: auto; }

@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }
body { animation: page-in 0.4s var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
}

/* --- arriving from the landing: the blue carries over ---
   The page opens still covered by the ground the landing was on, and
   that ground dissolves. Nothing animates the sequence itself — the
   scroll owns it — and this needs no script to run: a CSS animation
   with `both` fill leaves the veil transparent and out of the way
   whatever happens next. */
.page-veil {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg, var(--accent-deep) 0%, var(--navy-900) 78%);
  opacity: 0;
  visibility: hidden;
}
.page-veil img {
  width: clamp(200px, 24vw, 340px);
  height: auto;
  filter: brightness(0) invert(1);
  /* Matches the lockup on the landing, so where cross-document view
     transitions are supported the two are treated as one element. */
  view-transition-name: brand-lockup;
}
.is-entering .page-veil {
  visibility: visible;
  animation: veil-out 1.1s var(--ease) both;
}
@keyframes veil-out {
  0%, 20% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}
/* The landing has no header; fade it in rather than have it snap over
   the veil the instant the page loads. */
.is-entering .site-header { animation: page-in 0.7s var(--ease) 0.5s both; }

@media (prefers-reduced-motion: reduce) {
  .is-entering .page-veil { animation: none; visibility: hidden; }
  .is-entering .site-header { animation: none; }
}

/* ===========================================================
   Header
=========================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--rule);
}
.site-header .wrap {
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.site-header__logo img { height: 30px; width: auto; }
.site-header__nav { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.25rem); }
.site-header__links { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.25rem); }
.site-header__links a {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--navy);
  opacity: 0.72;
  transition: opacity 0.25s var(--ease);
}
.site-header__links a:hover { opacity: 1; }

/* The way back to the landing has to survive every width. The section
   anchors are page-local and can collapse on small screens; this one
   cannot, so it is the only link that stays. */
.site-header__home {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  opacity: 0.85;
}
.site-header__home::before { content: "←"; }
.site-header__home:hover { opacity: 1; }

@media (max-width: 680px) {
  .site-header__links a:not(.site-header__home) { display: none; }
}

/* Logo + "Accueil" + the call to action do not fit a phone at full
   size — the header is a flex row and none of the three can wrap, so
   without this the whole page gains a horizontal scrollbar. */
@media (max-width: 560px) {
  .site-header .wrap { gap: 0.5rem; }
  .site-header__nav,
  .site-header__links { gap: 0.75rem; }
  .site-header .btn { padding: 0.6rem 0.95rem; }
  .site-header__logo img { height: 26px; }
}

/* ===========================================================
   Sequence — the scroll-scrubbed centrepiece

   .seq is tall; .seq__stage sticks to the viewport for its whole
   height. js/main.js maps scroll progress onto both the drawn
   frame and which .seq__note is active, then hands over to the
   logo outro before releasing the page.
=========================================================== */
.seq {
  position: relative;
  height: 620vh;            /* pin length — the scroll budget */
  background: var(--paper);
}
.seq__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--paper);
}

/* --- the part: centred and large, the stage's real subject --- */
.seq__canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  /* Sized against the measured content extents of the sequence:
     the part spans 18.8%–75.0% of the frame while assembled and
     11.9%–87.0% at full explosion. These widths keep both ends of
     that range clear of the side panels. */
  width: min(60vw, 880px);
  height: min(66vh, 540px);
  background: var(--paper);
}

/* --- the commentary: one panel at a time, alternating sides ---
   Text sits above the canvas so the white it paints can never
   cover a caption; the part is held to the middle of the stage
   so the two never actually meet. */
.seq__intro,
.seq__note {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Intro is wider than the notes — it carries the headline while
   the part is still assembled and compact. */
.seq__intro {
  left: var(--gutter);
  width: min(26vw, 330px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.seq__intro.is-hidden { opacity: 0; transform: translateY(-50%) translateX(-24px); pointer-events: none; }
.seq__intro h1 { font-size: var(--fs-hero); margin-top: 1.4rem; text-wrap: balance; }
.seq__intro p { margin-top: 1.5rem; font-size: var(--fs-lead); color: var(--steel); }

/* Each note enters from its own side and leaves the same way, so
   a fading pair never crosses over the middle — or each other. */
.seq__note {
  width: clamp(220px, 20vw, 290px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), transform 0.55s var(--ease);
}
.seq__note[data-side="left"] { left: var(--gutter); transform: translateY(-50%) translateX(-30px); }
.seq__note[data-side="right"] { right: var(--gutter); transform: translateY(-50%) translateX(30px); text-align: right; }
.seq__note.is-active {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  pointer-events: auto;
}
.seq__note h2 { font-size: clamp(1.3rem, 1.9vw, 1.75rem); margin: 0.9rem 0 0.8rem; }
.seq__note p { color: var(--steel); font-size: var(--fs-small); }

/* --- outro: the brand resolve ---
   Unlike the rest of the sequence this block is driven by inline
   styles from js/main.js, because the mark has to land on the logo
   the video draws, and that position depends on the canvas's
   contain-fit box. CSS only sets what does not need measuring. */
.seq__outro {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

/* The saturated ground — still the only one on the page. */
.seq__outro-bg {
  position: absolute;
  inset: 0;
  background: linear-gradient(150deg, var(--accent-deep) 0%, var(--navy-900) 78%);
  opacity: 0;
}

/* Registered on the frame's logo, then travels to its slot inside
   the full lockup. Both copies share the wrapper's box so the
   navy → white change is a cross-fade, not a repaint. */
.seq__outro-mark { position: absolute; opacity: 0; }
.seq__outro-mark img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.seq__outro-mark-light { filter: brightness(0) invert(1); opacity: 0; }

/* The finished lockup. Its mark sits exactly where the travelling
   mark ends, so the hand-off is invisible. */
.seq__outro-brand {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: clamp(240px, 28vw, 380px);
  height: auto;
  filter: brightness(0) invert(1);
  opacity: 0;
}

.seq__outro-cue {
  position: absolute;
  left: 50%;
  bottom: 2rem;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--steel-200);
  opacity: 0;
}

.seq__cue {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  /* Below the outro (z-index 3): the cue stays lit for the whole
     scrub, so the logo panel has to be able to cover it during the
     crossfade rather than have navy text sit on a navy ground. */
  z-index: 2;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy);
  opacity: 0.9;
  transition: opacity 0.4s var(--ease);
  animation: bob 2.4s ease-in-out infinite;
}
.seq__cue.is-hidden { opacity: 0; }
@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 5px); }
}

/* Reduced motion: unpin, stack, show everything at once. */
.seq.is-static { height: auto; }
.seq.is-static .seq__stage {
  position: static;
  height: auto;
  overflow: visible;
  display: grid;
  gap: var(--sp-block);
  max-width: var(--max-w);
  margin-inline: auto;
  padding: var(--sp-section) var(--gutter) var(--sp-block);
}
.seq.is-static .seq__intro,
.seq.is-static .seq__note {
  position: static;
  width: auto;
  max-width: 60ch;
  opacity: 1;
  transform: none;
  text-align: left;
}
.seq.is-static .seq__canvas {
  position: static;
  transform: none;
  width: 100%;
  height: 58vh;
  order: -1;
}
.seq.is-static .seq__outro,
.seq.is-static .seq__cue { display: none; }

/* ===========================================================
   Formats — integrating a new product on an existing line.
   This is the core of the business, so it gets the widest
   section and the most room on the page.
=========================================================== */
.formats { background: var(--bone); padding-block: var(--sp-section); border-block: 1px solid var(--rule); }
.formats__grid {
  margin-top: var(--sp-block);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}
.format {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 2.2vw, 1.9rem);
  display: flex;
  flex-direction: column;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.format:hover { border-color: rgba(17, 60, 95, 0.28); transform: translateY(-2px); }
.format svg { width: 100%; height: auto; aspect-ratio: 3 / 2; margin-bottom: 1.4rem; }
.format h3 { font-size: var(--fs-h3); margin-bottom: 0.55rem; }
.format p { font-size: var(--fs-small); color: var(--steel); }

/* ===========================================================
   Process — datum axis, drawn on white
=========================================================== */
.process { background: var(--paper); padding-block: var(--sp-section); }
.process__axis { position: relative; margin-top: clamp(3.5rem, 7vw, 6rem); }
/* Full-bleed datum line: crosses the container margins so the
   section is tied to the page edges instead of floating in it. */
.process__axis::before {
  content: "";
  position: absolute;
  top: 2.35rem;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
}
.process__stations {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.station { position: relative; padding-top: 3.5rem; }
.station__idx {
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  color: var(--navy-600);
}
.station__tick { position: absolute; top: 1.85rem; left: 0; width: 1px; height: 1rem; background: var(--navy-600); opacity: 0.5; }
.station__tick::after {
  content: "";
  position: absolute;
  top: 0.35rem;
  left: -2.5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--navy);
}
.station h3 { font-size: var(--fs-h3); }
.station p { margin-top: 0.6rem; font-size: var(--fs-small); color: var(--steel); max-width: 30ch; }

/* ===========================================================
   Offers
=========================================================== */
.offers { background: var(--bone); padding-block: var(--sp-section); border-top: 1px solid var(--rule); }
.offers__grid {
  margin-top: var(--sp-block);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}
.offer {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
}
.offer h3 { font-size: clamp(1.25rem, 1.9vw, 1.6rem); margin: 0.9rem 0 0.85rem; }
.offer p { color: var(--steel); max-width: 40ch; }
.offer__list { margin-top: 1.5rem; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.offer__list li {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.06em;
  color: var(--navy-600);
  background: var(--bone);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0.4em 0.85em;
}

/* ===========================================================
   Contact
=========================================================== */
/* Tighter at the bottom than a normal section: this is the only
   place where white meets the dark footer, and a full --sp-section
   there reads as a gap rather than as breathing room. */
.contact { background: var(--paper); padding-block: var(--sp-section) calc(var(--sp-section) * 0.55); }
.contact .wrap {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: start;
}
.contact__intro h2 { font-size: var(--fs-h2); margin-top: 1.1rem; max-width: 14ch; }
.contact__intro p { margin-top: 1.4rem; color: var(--steel); max-width: 36ch; font-size: var(--fs-lead); }
.contact__location {
  display: block;
  margin-top: 2.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-600);
}

.form {
  background: var(--bone);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.field { margin-bottom: 1.15rem; }
.field label {
  display: block;
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.45rem;
  color: var(--navy);
}
.field label span { font-weight: 400; color: var(--steel); }
.field input,
.field textarea {
  width: 100%;
  font: inherit;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--steel-200);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  transition: border-color 0.25s var(--ease);
}
.field input:focus, .field textarea:focus { border-color: var(--navy-600); outline: none; }
.field textarea { resize: vertical; min-height: 124px; }
.form__submit { display: flex; align-items: center; gap: 1rem; margin-top: 0.75rem; flex-wrap: wrap; }
.form__status { font-size: var(--fs-small); color: var(--steel); }
.form__status[data-state="ok"] { color: #2f7a4f; }
.form__status[data-state="error"] { color: #b3492f; }

/* ===========================================================
   Footer — the one dark surface on the page
=========================================================== */
.site-footer { background: var(--navy-900); padding-block: clamp(2.5rem, 5vw, 3.5rem); }
.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  align-items: center;
  justify-content: space-between;
}
.site-footer__logo img { height: 24px; width: auto; filter: brightness(0) invert(1); opacity: 0.85; }
/* Wraps: this nav now carries cross-branch links, whose labels are far
   longer than the section anchors it used to hold. */
.site-footer__nav { display: flex; flex-wrap: wrap; gap: 0.75rem 1.75rem; }
.site-footer__nav a { font-size: var(--fs-small); color: var(--steel-200); opacity: 0.75; transition: opacity 0.25s var(--ease); }
.site-footer__nav a:hover { opacity: 1; }
.site-footer__meta {
  width: 100%;
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule-dark);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-200);
  opacity: 0.7;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ===========================================================
   Responsive
=========================================================== */
@media (max-width: 1040px) {
  .formats__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .contact .wrap { grid-template-columns: 1fr; }
  .offers__grid { grid-template-columns: 1fr; }
  .form__row { grid-template-columns: 1fr; }

  /* Axis rotates from horizontal datum to vertical, keeping the
     drafting device instead of degrading to a plain list. */
  .process__stations { grid-template-columns: 1fr; gap: 0; }
  .process__axis::before { top: 0; bottom: 0; left: 3px; right: auto; width: 1px; height: auto; }
  .station { padding: 0 0 2.25rem 2.25rem; }
  .station:last-child { padding-bottom: 0; }
  .station__idx { position: static; display: block; margin-bottom: 0.35rem; }
  .station__tick { top: 0.5rem; left: -2.25rem; width: 1rem; height: 1px; }
  .station__tick::after { top: -2.5px; left: 0.35rem; }
  .station p { max-width: 46ch; }

}

/* --- Sequence: stacked layout ---
   Side panels need real room. Measured against the part's actual
   extents (18.8%–75.0% assembled, 11.9%–87.0% exploded), the
   columns only clear it from about 1400px up; below that the
   panels would sit on the machined parts. So the part moves up,
   the commentary reads underneath it, and the panels still enter
   from alternating sides — the direction survives the breakpoint
   even though the position does not. */
@media (max-width: 1400px) {
  .seq { height: 560vh; }
  .seq__canvas {
    top: 36%;
    width: calc(100% - var(--gutter) * 2);
    height: min(46vh, 420px);
  }
  .seq__intro,
  .seq__note {
    top: auto;
    /* Leaves room for the scroll cue, which stays lit until the logo. */
    bottom: 11vh;
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    max-width: 46rem;
    transform: none;
    text-align: left;
  }
  .seq__intro.is-hidden { transform: translateX(-24px); }
  .seq__note[data-side="left"] { transform: translateX(-26px); }
  .seq__note[data-side="right"] { transform: translateX(26px); text-align: left; }
  .seq__note.is-active { transform: translateX(0); }
}

/* --- .seq--wide: a subject that reaches the frame edge ---
   The weighing machine is a long conveyor. Measured across every
   frame, it spans 0%–89% of the frame width — at its widest sweep it
   touches the left edge outright. Side panels are therefore only
   possible if the canvas itself is held narrower than the viewport by
   more than a panel's width, which is what the sizes below do. That
   costs some size on the machine, and it is the price of putting the
   commentary beside it rather than under it.

   Placed after the stacked block on purpose: it has to win back the
   side layout between 1250px and 1400px. */
@media (min-width: 1251px) {
  .seq--wide .seq__canvas {
    top: 50%;
    width: min(54vw, 780px);
    height: min(70vh, 620px);
  }
  .seq--wide .seq__intro,
  .seq--wide .seq__note {
    top: 50%;
    bottom: auto;
    width: clamp(190px, 16vw, 230px);
    max-width: none;
    transform: translateY(-50%);
  }
  .seq--wide .seq__intro { left: var(--gutter); right: auto; }
  .seq--wide .seq__intro.is-hidden { transform: translateY(-50%) translateX(-24px); }
  .seq--wide .seq__note[data-side="left"] {
    left: var(--gutter);
    right: auto;
    text-align: left;
    transform: translateY(-50%) translateX(-26px);
  }
  .seq--wide .seq__note[data-side="right"] {
    left: auto;
    right: var(--gutter);
    text-align: right;
    transform: translateY(-50%) translateX(26px);
  }
  .seq--wide .seq__note.is-active { transform: translateY(-50%) translateX(0); }
}

@media (max-width: 560px) {
  .formats__grid { grid-template-columns: 1fr; }
  .site-footer .wrap { flex-direction: column; align-items: flex-start; }
  .seq__canvas { top: 30%; height: 34vh; }
}
