/* =========================================================================
   Zurich AI Safety

   The page markup comes straight out of the Claude Design canvas export and
   keeps its inline styles, so the rendering matches the artboards exactly.
   This file only supplies what an inline style attribute cannot express:
   hover states, the nav dropdowns, disclosure state, keyframes, reduced
   motion and the mobile breakpoints.
   ========================================================================= */

@import url("./hover.css?v=20260918122722");

/* ---------- 1. Base ------------------------------------------------------ */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: #F7F3E7;
  color: #020522;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

a { color: #DE2C00; text-decoration: none; }
a:hover { color: #020522; }

img, canvas { display: block; max-width: 100%; }

[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid #DE2C00;
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: #DE2C00;
  color: #FFFFFF;
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
}
.skip-link:focus { left: 0; color: #FFFFFF; }

/* ---------- 2. Hero gradient (sitewide) ------------------------------------ */

/* Animated mesh-gradient hero background: two pre-rendered image sets (light
   "A" / dark "B") crossfading in a 10s loop. Used on every page's hero; the
   visitor-facing toggle sits once in the header nav (see the .set-toggle
   markup next to "Get Involved" in each page's header) and drives whichever
   #hero-gradient is on the current page. See assets/js/site.js for the
   toggle logic and localStorage persistence. */

.gradient, .grain { position: absolute; inset: 0; pointer-events: none; }
.gradient { z-index: 0; }
.grain { z-index: 1; }

.gradient-layer {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

/* set A — light neutral (#DE2C00 + #D0C0A9) */
.gradient[data-set="A"] .gl-base { background-image: url("/assets/img/gradient/setA-1.jpg"); }
.gradient[data-set="A"] .gl-2    { background-image: url("/assets/img/gradient/setA-2.jpg"); }
.gradient[data-set="A"] .gl-3    { background-image: url("/assets/img/gradient/setA-3.jpg"); }
.gradient[data-set="A"] .gl-4    { background-image: url("/assets/img/gradient/setA-4.jpg"); }
.gradient[data-set="A"] .gl-5    { background-image: url("/assets/img/gradient/setA-5.jpg"); }

/* set B — dark neutral (#DE2C00 + #020522) */
.gradient[data-set="B"] .gl-base { background-image: url("/assets/img/gradient/setB-1.jpg"); }
.gradient[data-set="B"] .gl-2    { background-image: url("/assets/img/gradient/setB-2.jpg"); }
.gradient[data-set="B"] .gl-3    { background-image: url("/assets/img/gradient/setB-3.jpg"); }
.gradient[data-set="B"] .gl-4    { background-image: url("/assets/img/gradient/setB-4.jpg"); }
.gradient[data-set="B"] .gl-5    { background-image: url("/assets/img/gradient/setB-5.jpg"); }

/* set C - blue duotone, matching the 4322 hero ramp */
.gradient[data-set="C"] .gl-base { background-image: url("/assets/img/gradient/setC-1.jpg"); }
.gradient[data-set="C"] .gl-2    { background-image: url("/assets/img/gradient/setC-2.jpg"); }
.gradient[data-set="C"] .gl-3    { background-image: url("/assets/img/gradient/setC-3.jpg"); }
.gradient[data-set="C"] .gl-4    { background-image: url("/assets/img/gradient/setC-4.jpg"); }
.gradient[data-set="C"] .gl-5    { background-image: url("/assets/img/gradient/setC-5.jpg"); }

/* set R - red, built to the same darkness as set C so both heroes read alike */
.gradient[data-set="R"] .gl-base { background-image: url("/assets/img/gradient/setR-1.jpg"); }
.gradient[data-set="R"] .gl-2    { background-image: url("/assets/img/gradient/setR-2.jpg"); }
.gradient[data-set="R"] .gl-3    { background-image: url("/assets/img/gradient/setR-3.jpg"); }
.gradient[data-set="R"] .gl-4    { background-image: url("/assets/img/gradient/setR-4.jpg"); }
.gradient[data-set="R"] .gl-5    { background-image: url("/assets/img/gradient/setR-5.jpg"); }

/* set D - the brand red from the earlier hero, deep red through to light coral */
.gradient[data-set="D"] .gl-base { background-image: url("/assets/img/gradient/setD-1.jpg"); }
.gradient[data-set="D"] .gl-2    { background-image: url("/assets/img/gradient/setD-2.jpg"); }
.gradient[data-set="D"] .gl-3    { background-image: url("/assets/img/gradient/setD-3.jpg"); }
.gradient[data-set="D"] .gl-4    { background-image: url("/assets/img/gradient/setD-4.jpg"); }
.gradient[data-set="D"] .gl-5    { background-image: url("/assets/img/gradient/setD-5.jpg"); }

.gl-2 { animation: fade-l2 45s linear infinite; }
.gl-3 { animation: fade-l3 45s linear infinite; }
.gl-4 { animation: fade-l4 45s linear infinite; }
.gl-5 { animation: fade-l5 45s linear infinite; }

/* One 45s linear loop: layers 2-5 fade out together over the first 2s,
   then each fades back in, one at a time, over the remaining 8s. */
@keyframes fade-l2 { 0%{opacity:1} 20%{opacity:0} 40%,100%{opacity:1} }
@keyframes fade-l3 { 0%{opacity:1} 20%,40%{opacity:0} 60%,100%{opacity:1} }
@keyframes fade-l4 { 0%{opacity:1} 20%,60%{opacity:0} 80%,100%{opacity:1} }
@keyframes fade-l5 { 0%{opacity:1} 20%,80%{opacity:0} 100%{opacity:1} }

.grain {
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-step 0.5s steps(4) infinite;
}
@keyframes grain-step {
  0% { transform: translate(0,0); }
  25% { transform: translate(-2%,1%); }
  50% { transform: translate(1%,-2%); }
  75% { transform: translate(-1%,-1%); }
  100% { transform: translate(0,0); }
}

/* Toggle lives inline in the header nav, next to "Get Involved" — see the
   header markup in each page's hero section. */
.set-toggle {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.4);
  background: rgba(0,0,0,0.15);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.set-toggle-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #D0C0A9;
  transition: background 0.2s ease;
}
/* The dot previews the palette you will get next. */
.set-toggle[data-next="C"] .set-toggle-dot { background: #2E6BF5; }
.set-toggle[data-next="R"] .set-toggle-dot { background: #DE2C00; }
.set-toggle[data-next="D"] .set-toggle-dot { background: #F2603C; }

/* ---------- 3. Sticky header ---------------------------------------------- */

/* Fixed to the top at all times (see the header-spacer right after </header>
   in the HTML, which reserves the space it used to occupy in normal flow).
   Transparent over the hero until the page scrolls past 24px, then a
   solid white bar with ink-coloured contents. */
.site-header {
  background: transparent;
  border-bottom: 1px solid rgba(255,255,255,0.3);
  transition: background-color 0.22s ease;
}
.site-header.is-compact {
  background: #FFFFFF;
  border-bottom-color: rgba(2,5,34,0.12);
}
/* Everything in the bar is white over the hero, so once the bar turns white
   the contents have to flip to ink. The link colours are inline styles, so
   these need !important to win. */
.site-header.is-compact a,
.site-header.is-compact nav span { color: #020522 !important; }
.site-header.is-compact a[href="/get-involved/"] {
  border-color: rgba(2,5,34,0.45) !important;
}
.site-header.is-compact a[href="/get-involved/"]:hover {
  background: #020522 !important;
  color: #FFFFFF !important;
  border-color: #020522 !important;
}
.site-header.is-compact .menu-toggle { border-color: rgba(2,5,34,0.45); }
.site-header.is-compact .menu-toggle span { background: #020522; }
.site-header.is-compact .set-toggle {
  border-color: rgba(2,5,34,0.28);
  background: rgba(2,5,34,0.06);
}
/* Header row shrinks on scroll (80px -> 64px) and is slightly shorter by
   default once the hamburger breakpoint kicks in (80px -> 72px), matching
   the reference exactly. The inline min-height:80px on the row is the
   default value, so only the two overrides need !important here. */
.site-header > div {
  transition: min-height 0.22s ease;
}
.site-header.is-compact > div {
  min-height: 64px !important;
}
@media (max-width: 1060px) {
  .site-header > div {
    min-height: 72px !important;
  }
}

/* ---------- 4. Nav dropdowns --------------------------------------------- */

/* The export drove these from component state on mouseenter/mouseleave.
   Hover plus focus-within does the same job without script, and keeps the
   menus reachable from the keyboard. Kept in the DOM (not display:none) and
   faded + slid in on open so the menu animates instead of snapping. */
[data-dropdown] > div {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0.18s;
}

/* Open on the label itself (or the open menu), not on the whole stretched
   column - the wrapper is the full height of the header, so hovering anywhere
   in that strip used to trigger it. The label is stretched to full height so
   there is no gap to cross on the way down to the menu. */
[data-menu] > span { align-self: stretch; }

[data-menu] > span:hover + [data-dropdown] > div,
[data-menu] > [data-dropdown]:hover > div,
[data-menu]:focus-within > [data-dropdown] > div {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition: opacity 0.18s ease, transform 0.18s ease;
}

/* Current-page underline, applied dynamically by initNavCurrent() in
   site.js (compares location.pathname to each top-level link's href)
   instead of being hardcoded per page. */
header nav > a[data-nav-current] {
  border-bottom: 1.5px solid #FFFFFF;
  padding-bottom: 2px;
}
.mobile-nav-links > a[data-nav-current] {
  align-self: flex-start;
  border-bottom: 1.5px solid #020522;
  padding-bottom: 4px;
}

/* ---------- 5. Disclosure wrappers --------------------------------------- */

/* These wrap content the canvas showed or hid conditionally. display:contents
   keeps them out of the layout entirely, so the grid and flex parents behave
   exactly as they did in the artboard. */
.editorial-note { display: contents; }

/* Working notes carried over from the design canvas. They are addressed to the
   ZAIS team, not to visitors — hide them before launch by adding the class
   `hide-editorial-notes` to <body>. */
body.hide-editorial-notes .editorial-note { display: none; }

/* ---------- 6. Carousels -------------------------------------------------- */

[data-carousel-track] { will-change: transform; }

[data-tl-scroll] { scrollbar-width: none; }
[data-tl-scroll]::-webkit-scrollbar { display: none; }

/* ---------- 7. Mobile ----------------------------------------------------- */

/* The export authored no breakpoints — it relies on flex-wrap and auto-fit
   grids. Two places still overflow on a phone, so they are handled here. */
/* Hamburger trigger: hidden on desktop, shown below 1060px. */
.menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  border: 1.5px dashed rgba(255,255,255,0.85);
  border-radius: 100px;
  background: transparent;
  cursor: pointer;
}
.menu-toggle span {
  display: block;
  width: 100%;
  height: 1.5px;
  background: #FFFFFF;
}

/* Full-screen mobile nav overlay, opened by the hamburger. Hidden via
   opacity/visibility (not display) so it can fade in rather than snap. */
.mobile-nav-panel {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: #FFFFFF;
  padding: 20px 40px 32px;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  gap: 32px;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-12px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
}
.mobile-nav-panel.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition: opacity 0.24s ease, transform 0.24s ease;
}
.mobile-nav-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: none;
}
.mobile-nav-brand {
  font-family: 'Geist', sans-serif;
  font-size: 20px;
  white-space: nowrap;
  font-weight: 600;
  letter-spacing: normal;
  color: #020522;
}
.mobile-nav-close {
  width: 44px;
  height: 44px;
  border: 1.5px dashed #020522;
  border-radius: 100px;
  background: transparent;
  color: #020522;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  flex: none;
}
.mobile-nav-links {
  display: flex;
  flex-direction: column;
  gap: 22px;
  flex: none;
}
/* Top-level items (Home, About ZAIS, Research) and the group headers
   (Programmes, Events) share the same large style, same as the reference -
   only the sub-links underneath a group are smaller and lighter. */
.mobile-nav-links > a,
.mobile-nav-group {
  font-family: 'Inter', sans-serif;
  font-size: clamp(22px,6vw,28px);
  font-weight: 400;
  letter-spacing: normal;
  color: #020522;
}
.mobile-nav-group { margin-bottom: -4px; }
.mobile-nav-links > a.mobile-nav-sublink {
  font-family: 'Inter', sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: rgba(2,5,34,0.78);
  letter-spacing: normal;
}
/* Each row rises in as the panel opens. The animation is keyed to .is-open,
   which is toggled on every open/close, so it replays each time rather than
   only on the first opening. Delays are set per row by site.js. */
.mobile-nav-panel.is-open [data-menu-entrance] {
  animation: mobile-nav-item-enter 420ms cubic-bezier(.22,.61,.36,1) both;
  animation-delay: var(--menu-item-delay, 0ms);
}
@keyframes mobile-nav-item-enter {
  from { opacity: 0; translate: 0 12px; }
  to   { opacity: 1; translate: 0 0; }
}

.mobile-nav-bottom-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
}
.mobile-nav-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 15px 30px;
  border: 1.5px dashed #DE2C00;
  border-radius: 100px;
  color: #DE2C00;
  font-family: 'Inter', sans-serif;
  font-size: 15px;
  font-weight: 500;
}
body.mobile-nav-open { overflow: hidden; }

@media (max-width: 1060px) {
  /* Below this width the inline nav row and Get Involved pill are replaced
     by the hamburger + full-screen overlay above; only the logo, the theme
     toggle and the hamburger stay in the header row. */
  header nav,
  header > div > div[style*="justify-self:end"] > a[href="/get-involved/"] {
    display: none !important;
  }
  .menu-toggle { display: flex; }
}

@media (max-width: 720px) {
  /* Programme grid on the homepage is a hard 2-up. */
  [data-screen-label="Programmes"] div[style*="grid-template-columns:repeat(2"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  /* Past-events mosaic is a hard 4-up. */
  [data-screen-label="Community"] div[style*="grid-template-columns:repeat(4"] {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* ---------- 8. Scroll reveal ----------------------------------------------- */

/* Section headings and their intro paragraph fade in and rise slightly as
   they scroll into view. The "reveal-pending" class is added by JS
   (assets/js/site.js, initScrollReveal), never baked into the HTML, so a
   visitor with JS disabled or slow to load always sees the content  - 
   nothing depends on the animation to become visible. A heading and the
   paragraph right after it reveal in a quick one-two via the transition
   delay below, not simultaneously. */
.reveal-pending {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal-pending.reveal-visible {
  opacity: 1;
  transform: none;
}
h1.reveal-pending + p.reveal-pending,
h2.reveal-pending + p.reveal-pending,
h3.reveal-pending + p.reveal-pending {
  transition-delay: 0.12s;
}

/* Headings/paragraphs marked data-reveal use this instead of the block
   fade above: each word dims to 25% until it scrolls up past a line near
   the bottom of the viewport, then brightens to full color - a "typewriter"
   style reveal that plays out as you scroll rather than firing once. Words
   are wrapped in .wr-word spans by wrapWords() in site.js; without JS the
   text is never wrapped and simply shows at full opacity. */
.wr-word {
  opacity: 0.25;
  transition: opacity 0.4s ease;
}
.wr-word.wr-lit {
  opacity: 1;
}

/* ---------- 9. Carousel and tab delighters -------------------------------- */

/* Voice/testimonial carousel cards: no hover animation beyond the quote overlay fade on the photo. */

/* Past-events photo mosaic: static grid, no hover animation. */

/* Curriculum session tabs: an inactive tab nudges right and tints toward
   the accent on hover, hinting it's clickable; the detail panel plays a
   quick fade-and-rise every time it's switched in. Colors need !important
   because initSessionTabs() sets them inline in site.js. */
[data-action="selectSession"] {
  transition: transform 0.2s ease !important;
}
[data-action="selectSession"]:hover {
  transform: translateX(4px) !important;
}
[data-action="selectSession"]:not([data-active="true"]):hover [data-session-num],
[data-action="selectSession"]:not([data-active="true"]):hover [data-session-title] {
  color: rgba(222,44,0,0.6) !important;
}
[data-session-detail-panel] {
  animation: session-fade-in 0.35s ease;
}
@keyframes session-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- 10. Where To Start 02 (experiment) ------------------------------ */

/* Prototype list-row layout for the Programmes section, sitting right after
   Our Mission so it can be compared against the existing "Where To Start"
   grid. Remove this block and its <section> in index.html once a direction
   is picked. */
[data-programme-row] {
  transition: background-color 0.2s ease;
}
[data-programme-row]:hover {
  background-color: rgba(2,5,34,0.03);
}
[data-programme-row]:hover [data-row-title] {
  color: #DE2C00 !important;
}
[data-programme-row]:hover [data-row-arrow] {
  background: #DE2C00 !important;
  color: #FFFFFF !important;
  border-color: #DE2C00 !important;
}

/* ---------- 11. Drag-scroll cards (Where To Start 03 experiment) ----------- */

/* Horizontal card row the visitor drags sideways with the mouse; no
   scrollbar, no arrow buttons. Touchscreens already scroll it natively
   with a swipe — this is a mouse-only affordance on top of that.
   Remove this block and its <section> in index.html once a direction
   is picked. */
[data-drag-scroll] {
  scrollbar-width: none;
  -ms-overflow-style: none;
  cursor: none;
  -webkit-overflow-scrolling: touch;
}
[data-drag-scroll]::-webkit-scrollbar {
  display: none;
}
[data-drag-scroll].is-dragging {
  user-select: none;
}

.drag-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 46px;
  height: 46px;
  border-radius: 999px;
  background: rgba(2, 5, 34, 0.86);
  backdrop-filter: blur(3px);
  color: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  pointer-events: none;
  opacity: 0;
  transform-origin: center;
  transition: opacity 0.2s ease;
  z-index: 60;
}
.drag-cursor.is-visible {
  opacity: 0.96;
}

/* Anything clickable inside the row keeps its own pointer, and the JS hides
   the DRAG bubble while you are over one - it is a hint for the empty space
   between cards, not for the links themselves. */
[data-drag-scroll] a,
[data-drag-scroll] button {
  cursor: pointer;
}

/* ---------- 12. Story timeline (zig-zag, scroll-progress) ----------------- */

/* Replaces the old boxed-card row: milestones sit directly on the section
   background, alternating above/below a horizontal line whose orange
   segment fills to match scroll progress. Built with CSS subgrid so each
   milestone's icon/date/heading/paragraph block and its dot on the line
   share the outer grid's row tracks precisely. */

.timeline-viewport {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding: 6px 0 20px;
  scrollbar-width: none;
}
.timeline-viewport::-webkit-scrollbar { display: none; }

.timeline-track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(7, minmax(240px, 340px));
  grid-template-rows: auto 48px auto;
  column-gap: clamp(24px, 3vw, 36px);
  width: max-content;
  list-style: none;
  margin: 0;
  padding: 0;
}
.timeline-track::before, .timeline-track::after {
  content: "";
  grid-area: 2 / 1 / auto / -1;
  align-self: center;
  height: 1px;
  background: rgba(2, 5, 34, 0.2);
  pointer-events: none;
}
.timeline-track::after {
  background: #DE2C00;
  transform: scaleX(var(--timeline-progress, 0));
  transform-origin: left center;
}
.timeline-milestone {
  display: grid;
  grid-row: 1 / 4;
  grid-template-rows: subgrid;
  position: relative;
  min-width: 0;
}
.timeline-milestone:nth-child(1) { grid-column: 1; }
.timeline-milestone:nth-child(2) { grid-column: 2; }
.timeline-milestone:nth-child(3) { grid-column: 3; }
.timeline-milestone:nth-child(4) { grid-column: 4; }
.timeline-milestone:nth-child(5) { grid-column: 5; }
.timeline-milestone:nth-child(6) { grid-column: 6; }
.timeline-milestone:nth-child(7) { grid-column: 7; }
.timeline-node {
  grid-row: 2;
  align-self: center;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #020522;
  z-index: 1;
}
.timeline-milestone-accent .timeline-node { background: #DE2C00; }
.timeline-copy { grid-row: 1; align-self: end; }
.timeline-milestone:nth-child(2n) .timeline-copy { grid-row: 3; align-self: start; }
.timeline-meta { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.timeline-copy h3 { margin-bottom: 12px !important; }
.timeline-copy p + div { margin-top: 16px !important; }

.timeline-navigation { display: flex; justify-content: flex-end; align-items: center; gap: 20px; margin-top: clamp(20px, 2.5vw, 28px); }
.timeline-controls { display: flex; gap: 10px; }
.timeline-arrow {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 1.5px dashed #020522;
  border-radius: 100px;
  background: transparent;
  color: #020522;
  font: 20px 'Inter', sans-serif;
  cursor: pointer;
}
.timeline-arrow:hover:not(:disabled) { background: #020522; color: #F7F3E7; }
.timeline-arrow:disabled { opacity: 0.3; cursor: default; }

@media (max-width: 760px) {
  /* The timeline stays horizontal on small screens - it just gets narrower
     cards and keeps its swipe. The old rule here turned it into a vertical
     list, which lost the sense of a track running through time. */
  .timeline-track {
    grid-template-columns: repeat(7, minmax(225px, 78vw));
    grid-template-rows: auto 40px auto;
    column-gap: 20px;
  }
  .timeline-viewport {
    padding: 6px 0 16px;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
  }
  .timeline-milestone { scroll-snap-align: start; }
  .timeline-copy h3 { font-size: 20px !important; }
  .timeline-copy p { font-size: 14px !important; }
  .timeline-navigation { display: flex; }
}

/* ---------- 13. Reduced motion ---------------------------------------------- */

/* ---------- Voice cards (homepage) ---------------------------------------
   Carried over from the modular build. hover.css only reveals the quote
   overlay on :hover, which leaves it unreachable by keyboard; :focus-within
   gives the same reveal when the card's link is tabbed to. The overflow and
   size clamp keep the longer quotes readable inside the portrait crop. */
[data-voice-card] { min-width: 0; }
[data-voice-card] [data-hv="hv6"] {
  overflow-y: auto;
  padding: clamp(18px, 2.2vw, 30px) !important;
}
[data-voice-card] [data-hv="hv6"] p {
  font-size: clamp(14px, 1.25vw, 18px) !important;
}
[data-voice-card]:focus-within [data-hv="hv6"] { opacity: 1 !important; }
@media (prefers-reduced-motion: reduce) {
  [data-voice-card] [data-hv="hv6"] { transition: none !important; }
}

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


/* Hero palette switching. Red and blue are now the same treatment on two
   palettes: unmasked weights over a dark ground with the full scrim. The
   red set is built to match the blue set's luminance, so nothing else
   needs to change between them. */
[data-palette] canvas.hero-binary { -webkit-mask-image: none; mask-image: none; }
[data-hero-scrim] { transition: opacity .4s ease, background-image .4s ease; }

/* The scrim is hardcoded navy in the markup, which tinted the left edge of
   every hero blue whatever the palette. Each palette gets its own dark end
   instead, so the red versions start red and stay red. */
[data-palette="R"] [data-hero-scrim] {
  background-image: linear-gradient(100deg, rgba(40,9,4,0.96) 0%, rgba(40,9,4,0.92) 34%, rgba(40,9,4,0.72) 52%, rgba(40,9,4,0.34) 70%, rgba(40,9,4,0.08) 86%), radial-gradient(70% 76% at 24% 50%, rgba(40,9,4,0.82) 0%, rgba(40,9,4,0.50) 46%, rgba(40,9,4,0) 88%) !important;
}
[data-palette="D"] [data-hero-scrim] {
  background-image: linear-gradient(100deg, rgba(58,12,4,0.96) 0%, rgba(58,12,4,0.92) 34%, rgba(58,12,4,0.72) 52%, rgba(58,12,4,0.34) 70%, rgba(58,12,4,0.08) 86%), radial-gradient(70% 76% at 24% 50%, rgba(58,12,4,0.82) 0%, rgba(58,12,4,0.50) 46%, rgba(58,12,4,0) 88%) !important;
}

/* Palette A is the original build's sand-and-coral gradient. It is far lighter
   than the others, so it needs its own handling: a warmer, much weaker scrim
   that leaves the sand character intact (white on it reaches 7:1, against
   3.75:1 unscrimmed), and the weights masked to the darker areas so they are
   not lost in the pale half. */
[data-palette="A"] [data-hero-scrim] {
  background-image:
    linear-gradient(100deg, rgba(110,21,8,0.62) 0%, rgba(110,21,8,0.54) 34%,
      rgba(110,21,8,0.34) 52%, rgba(110,21,8,0.15) 70%, rgba(110,21,8,0.04) 86%),
    radial-gradient(70% 76% at 24% 50%, rgba(110,21,8,0.38) 0%,
      rgba(110,21,8,0.20) 46%, rgba(110,21,8,0) 88%) !important;
}
[data-palette="A"] canvas.hero-binary {
  -webkit-mask-image: url("/assets/img/gradient/setA-weights-mask.png");
          mask-image: url("/assets/img/gradient/setA-weights-mask.png");
  -webkit-mask-size: cover;       mask-size: cover;
  -webkit-mask-position: 50% 50%; mask-position: 50% 50%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.set-toggle[data-next="A"] .set-toggle-dot { background: #D0C0A9; }

/* PEAKS photo strip: five pictures, so five columns on desktop rather than
   letting auto-fit settle on four and orphan the last one. */
@media (max-width: 900px) { .peaks-photos { grid-template-columns: repeat(3, 1fr) !important; } }
@media (max-width: 560px) { .peaks-photos { grid-template-columns: repeat(2, 1fr) !important; } }

/* ==== Mobile refinements ============================================== */

/* Hero action buttons sit side by side instead of stacking. */
@media (max-width: 600px) {
  .hero-actions {
    display: flex !important;
    flex-wrap: nowrap !important;
    gap: 12px !important;
    width: 100%;
  }
  .hero-actions > a {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    text-align: center;
    padding: 14px 10px !important;
    font-size: 14px !important;
    white-space: nowrap;
  }
}

/* Why Zurich stats become a swipeable slider. */
.stat-dots { display: none; }
@media (max-width: 760px) {
  .why-stats {
    display: flex !important;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .why-stats::-webkit-scrollbar { width: 0; height: 0; display: none; }
  .why-stats > div {
    flex: 0 0 66%;
    scroll-snap-align: center;
    border-right: 1.5px dashed rgba(255, 255, 255, 0.28);
  }
  .why-stats > div:last-child { border-right: none; }

  .stat-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 18px;
  }
  .stat-dot {
    all: unset;
    cursor: pointer;
    width: 7px;
    height: 7px;
    border-radius: 100px;
    background: rgba(255, 255, 255, 0.28);
    transition: background .2s ease, width .2s ease;
  }
  .stat-dot[data-active="true"] { background: #FFFFFF; width: 18px; }
}

/* Programme chapters stack, with the detail text flying out on tap. */
@media (max-width: 760px) {
  [data-session-widget] { grid-template-columns: 1fr !important; }
  [data-session-list] { padding-right: 0 !important; }
  [data-action="selectSession"] {
    grid-template-columns: 26px 1fr 20px !important;
    border-bottom: 1px solid rgba(2, 5, 34, 0.12);
    padding: 15px 0 !important;
  }
  [data-action="selectSession"]::after {
    content: "";
    width: 9px;
    height: 9px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    transition: transform .22s ease;
    align-self: center;
    justify-self: end;
    color: rgba(2, 5, 34, 0.42);
  }
  [data-action="selectSession"][data-active="true"] {
    border-bottom-color: transparent;
  }
  [data-action="selectSession"][data-active="true"]::after {
    transform: rotate(-135deg) translate(-3px, -3px);
    color: #DE2C00;
  }
  [data-session-flyout] {
    padding: 2px 0 22px 40px;
    border-bottom: 1px solid rgba(2, 5, 34, 0.12);
  }
}

/* Team overview keeps two columns on narrow screens. */
@media (max-width: 760px) {
  .team-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: clamp(18px, 4vw, 26px) !important;
  }
  .team-grid > div { min-width: 0; }
  .team-grid a[data-hv="hv4"] { font-size: 17px !important; }
}
/* At phone width the name and the contact icons stop fighting for the row. */
@media (max-width: 460px) {
  .team-grid > div > div:last-child {
    flex-direction: column;
    align-items: flex-start !important;
    gap: 10px !important;
  }
}
/* Smaller contact buttons on phones. */
@media (max-width: 760px) {
  .team-grid a[data-hv="hv9"] {
    width: 27px !important;
    height: 27px !important;
    border-width: 1.2px !important;
  }
  .team-grid a[data-hv="hv9"] svg {
    width: 12px;
    height: 12px;
  }
  .team-grid a[data-hv="hv9"] + a[data-hv="hv9"] { margin-left: -1px; }
}

/* Colour switcher hidden in the nav. The palette machinery stays in place
   (pages keep their default set); only the control is removed. */
.set-toggle { display: none !important; }

/* Stay-in-the-loop banner: buttons go full width side by side on phones. */
@media (max-width: 760px) {
  .loop-actions {
    justify-content: flex-start !important;
    flex-wrap: nowrap !important;
  }
  .loop-actions > a {
    flex: 1 1 0;
    min-width: 0;
    padding: 13px 10px !important;
    font-size: 14px !important;
  }
}

/* Why Zurich: image and text stack on narrow screens. */
@media (max-width: 860px) {
  .why-grid { grid-template-columns: 1fr !important; }
}
