/* =========================================================
   MSCinteract · home.css
   Home tab: hero / dataset catalogue / walkthrough
   ========================================================= */

.home { display: flex; flex-direction: column; gap: 56px; }

/* ---------------- Hero ---------------- */

.hero {
  position: relative;
  overflow: hidden;
  /* keeps the light patches of the pseudo elements behind the content but
     above the background of the card */
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(320px, .85fr);
  gap: 34px;
  align-items: center;
  padding: 40px 42px;
  border-radius: 22px;
  border: 1px solid var(--line);
  /* two soft patches that slowly cross each other: the third layer of the
     moving background, underneath the drifting pseudo elements */
  background:
    radial-gradient(72% 92% at 10% 6%, rgba(18, 179, 166, .16), rgba(18, 179, 166, 0) 62%),
    radial-gradient(64% 84% at 90% 94%, rgba(47, 109, 246, .15), rgba(47, 109, 246, 0) 60%),
    linear-gradient(180deg, #fdfefe, #f2f7ff);
  background-size: 190% 190%, 190% 190%, 100% 100%;
  background-repeat: no-repeat;
  animation: hero-sheen 22s ease-in-out infinite alternate;
  box-shadow: var(--shadow-sm);
}

@keyframes hero-sheen {
  0%   { background-position: 0% 0%, 100% 100%, 0 0; }
  100% { background-position: 100% 100%, 0% 0%, 0 0; }
}

/* The content sits above the dot grid and above the light patches.
   (.hero__stats already carries the same stacking rule further down.) */
.hero__text {
  position: relative;
  z-index: 1;
}

/* The dot grid of the card. It answers the pointer, so it must never catch a
   click: the buttons of the hero stay clickable through it. */
.hero__dots {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* A beam of light turning slowly behind the card. It is the layer that makes
   the background of this card visibly alive, the patches around it only add
   the colour. */
.hero__beam {
  position: absolute;
  inset: -35%;
  z-index: -1;
  pointer-events: none;
  background: conic-gradient(from 0deg at 50% 50%,
    rgba(18, 179, 166, 0) 0deg,
    rgba(18, 179, 166, .38) 34deg,
    rgba(255, 255, 255, .60) 58deg,
    rgba(47, 109, 246, .36) 86deg,
    rgba(47, 109, 246, 0) 140deg,
    rgba(18, 179, 166, 0) 360deg);
  filter: blur(34px);
  -webkit-mask-image: radial-gradient(closest-side, #000 25%, rgba(0, 0, 0, .35) 62%, transparent 88%);
  mask-image: radial-gradient(closest-side, #000 25%, rgba(0, 0, 0, .35) 62%, transparent 88%);
  animation: hero-beam 42s linear infinite;
}

@keyframes hero-beam {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Two large light patches drifting slowly across the card: the background of
   this card alone is alive, the rest of the page stays still. They are
   painted behind the content, so the text keeps its full contrast. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(30px) saturate(1.35);
  will-change: transform, opacity;
}

.hero::before {
  top: -62%;
  left: -38%;
  width: 128%;
  height: 165%;
  background: radial-gradient(58% 58% at 50% 50%, rgba(18, 179, 166, .46), rgba(18, 179, 166, 0) 74%);
  animation: hero-light-a 14s ease-in-out infinite alternate;
}

.hero::after {
  top: 6%;
  right: -34%;
  width: 112%;
  height: 150%;
  background: radial-gradient(58% 58% at 50% 50%, rgba(47, 109, 246, .44), rgba(47, 109, 246, 0) 74%);
  animation: hero-light-b 19s ease-in-out infinite alternate;
}

@keyframes hero-light-a {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: .70; }
  45%  { transform: translate3d(13%, 9%, 0) scale(1.18); opacity: 1; }
  100% { transform: translate3d(30%, 22%, 0) scale(1.42); opacity: .88; }
}

@keyframes hero-light-b {
  0%   { transform: translate3d(0, 0, 0) scale(1.06); opacity: .66; }
  45%  { transform: translate3d(-15%, 13%, 0) scale(1.24); opacity: 1; }
  100% { transform: translate3d(-28%, 8%, 0) scale(1.48); opacity: .86; }
}

/* the movement is decoration: it is switched off when the reader asks for
   a still interface */
@media (prefers-reduced-motion: reduce) {
  .hero,
  .hero::before,
  .hero::after,
  .hero__beam { animation: none; }
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .75);
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  max-width: 100%;
  flex-wrap: wrap;
  overflow-wrap: break-word;
}

.hero__title {
  margin: 14px 0 10px;
  font-size: clamp(30px, 4vw, 46px);
  letter-spacing: -.03em;
  line-height: 1.08;
}
/* The words in colour. The fill runs the other way across the words than the
   light of the card drifts behind them — blue on the upper side, teal below —
   and its teal end is a shade deeper than the light, so the letters keep
   their shape whatever passes behind them. */
.hero__title em {
  font-style: normal;
  background: linear-gradient(150deg, #4a83f9 0%, #2f6df6 38%, #0d9488 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lead {
  font-size: 15px;
  color: var(--ink);
  max-width: 56ch;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }

.hero__stats {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.hero-stat {
  /* frosted glass: the drifting light of the card shows through the panel and
     gets scattered by the blur */
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(255, 255, 255, .72);
  border-radius: var(--radius);
  padding: 14px 16px;
  backdrop-filter: blur(16px) saturate(1.6);
  -webkit-backdrop-filter: blur(16px) saturate(1.6);
  box-shadow: 0 1px 2px rgba(18, 38, 76, .05), inset 0 1px 0 rgba(255, 255, 255, .75);
}
/* without the blur the panel has to be more opaque, otherwise the numbers sit
   on an unreadable background */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero-stat {
    background: rgba(255, 255, 255, .9);
    border-color: var(--line);
  }
}
.hero-stat__value { font-size: 22px; font-weight: 680; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.hero-stat__label { font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-top: 2px; }
.hero-stat--wide { grid-column: 1 / -1; }

/* ---------------- Sections ---------------- */

.section { display: flex; flex-direction: column; gap: 18px; }
.section__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
/* the title + description block takes the whole row instead of shrinking to
   the text width, so the paragraph is not stranded on the left */
.section__lead { flex: 1 1 100%; min-width: 0; }
.section__title { font-size: 21px; letter-spacing: -.02em; }
.section__desc { font-size: 13.5px; color: var(--muted); }

/* ---------------- Dataset cards ---------------- */

.dataset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 14px;
}

.dataset-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 17px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.dataset-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: var(--line-strong); }
.dataset-card.is-active { border-color: #bcd4ff; box-shadow: 0 6px 22px rgba(47, 109, 246, .12); }

/* The chips float at the right edge of the card and the name wraps around
   them. That keeps them in the corner without squeezing the name into a
   narrow strip the way a shared flex row would. */
.dataset-card__top { min-width: 0; }
.dataset-card__ident { min-width: 0; }
/* The chips sit at the right edge of the card, as one group. The group keeps
   its own width, so the two chips stay on a single line. */
.dataset-card__chips {
  float: right;
  margin: 0 0 4px 10px;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
}
/* The name holds the float, so it does not run under the chips. */
.dataset-card__name { display: flow-root; font-size: 15px; font-weight: 650; overflow-wrap: break-word; word-break: normal; }
.dataset-card__file { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-top: 2px; overflow-wrap: break-word; word-break: normal; }
.dataset-card__desc { font-size: 13.5px; color: var(--ink-soft); flex: 1; }
.dataset-card__meta { display: flex; flex-wrap: wrap; gap: 6px; }
.dataset-card__source { font-size: 12px; color: var(--muted); }
.dataset-card__ref { font-family: var(--mono); }
.dataset-card__source a { color: var(--accent); text-decoration: none; }
/* the address of the source answers the pointer with its colour */
.dataset-card__source a:hover { color: var(--accent-dark); }
.dataset-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }
.dataset-card__size { font-size: 12px; color: var(--muted); font-family: var(--mono); }

/* On a narrow screen there is no room for the two chips on one line, so they
   are allowed to stack there, and only there. They also stop floating: with
   so little width, the name needs every line it can get. */
@media (max-width: 640px) {
  .dataset-card__chips {
    float: none;
    margin: 0 0 6px;
    flex-wrap: wrap;
  }
}

@media (max-width: 980px) {
  .hero { grid-template-columns: 1fr; padding: 28px 24px; }
  .hero__stats { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
  .home { gap: 40px; }

  /* The greeting on a phone. The card is read close to the eye: the title
     takes a step down, the buttons stand one under the other with a target a
     finger can hit, and the four numbers keep their two columns, so that the
     card does not grow into a long list. */
  .hero {
    padding: 20px 16px;
    border-radius: 16px;
    gap: 20px;
  }
  .hero__eyebrow { font-size: 11px; letter-spacing: .02em; padding: 4px 9px; }
  .hero__title { font-size: 28px; margin: 12px 0 8px; }
  .hero__lead { font-size: 14px; }
  .hero__actions { display: grid; grid-template-columns: 1fr; gap: 8px; margin-top: 18px; }
  .hero__stats { gap: 8px; }
  .hero-stat { padding: 11px 12px; }
  .hero-stat__value { font-size: 19px; }
  .hero-stat__label { font-size: 10px; letter-spacing: .04em; }
}

/* The movement of the card is decoration, and on a phone it costs more than it
   gives: two of the layers repaint the whole card on every frame. The turning
   beam and the sheen that moves the background step out on a phone. The two
   drifting patches stay: they are cheap, they are composited, and they are
   what makes the card look alive. The dot grid is painted once and stays
   still - that part is in js/tabs/home/heroDots.js. */
@media (max-width: 760px) {
  .hero { animation: none; }
  .hero__beam { display: none; }
}

/* ---------------- Tool cards ---------------- */

.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 14px;
}

.tool-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 17px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.tool-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: var(--line-strong); }
.tool-card.is-active { border-color: #bcd4ff; box-shadow: 0 6px 22px rgba(47, 109, 246, .12); }

/* A tool that is not there yet stays quiet: it is announced, not offered. */
.tool-card--planned { background: #fbfcfe; }
.tool-card--planned .tool-card__name { color: var(--ink-soft); }

/* The chips float at the right edge of the card and the name wraps around
   them, the same way the dataset cards do it. */
.tool-card__name { display: flow-root; font-size: 15px; font-weight: 650; overflow-wrap: break-word; }
.tool-card__chips {
  float: right;
  margin: 0 0 4px 10px;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
}
.tool-card__id { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-top: 2px; overflow-wrap: break-word; }
.tool-card__desc { font-size: 13.5px; color: var(--ink-soft); flex: 1; }
.tool-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }
.tool-card__meta { font-size: 12px; color: var(--muted); font-family: var(--mono); }

@media (max-width: 640px) {
  .tool-card__chips {
    float: none;
    margin: 0 0 6px;
    flex-wrap: wrap;
  }
}

/* ---------------- Partners & funding ---------------- */

/* a plain grid of logos: no tiles, no frames.
   Three fixed columns keep the six marks on exactly two rows on a normal
   screen; on a wide screen they collapse into a single row (see below). */
.partner-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: 32px 40px;
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 20px;
}

.partner-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0;
}

/* every logo keeps its own proportions but shares one height */
.partner-item__link {
  position: relative;
  display: block;
  text-decoration: none;
  border-radius: 6px;
}
.partner-item__link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 5px;
}
/* The logo sits in a slot of a fixed height: the image fills the slot and is
   centred in it, so every mark is vertically aligned with its neighbours. */
.partner-item__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: calc(46px * var(--partner-scale, 1));
  width: 100%;
}
.partner-item__logo img {
  /* A mark may be zoomed: it then grows past the width of its own column and
     reaches into the gap on either side, where there is room for it. `flex:
     none` keeps it from shrinking back into the column. */
  width: calc(100% * var(--partner-zoom, 1));
  flex: none;
  height: 100%;
  max-width: none;
  max-height: 100%;
  object-fit: contain;
  transition: opacity .16s ease;
}
.partner-item:hover .partner-item__logo img { opacity: .7; }

/* Wide screens: the six marks fit on one single row. Every column receives
   a share of the width proportional to the ratio of its own logo, so all of
   them keep the same height and simply shrink until the row fits. */
@media (min-width: 1200px) {
  .partner-strip {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: clamp(14px, 1.6vw, 30px);
    max-width: 1600px;
  }
  .partner-item {
    flex: var(--partner-ratio, 1) 1 0;
    min-width: 0;
  }
  /* one common slot height for the whole row: the images are centred in it
     and therefore share one line */
  .partner-item__logo { height: 76px; }
  .partner-item__logo img {
    width: calc(100% * var(--partner-zoom, 1));
    height: 100%;
    max-height: none;
    object-fit: contain;
  }
}

/* hover tooltip: role on top, grant number below in mono */
.partner-item__tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 10px);
  z-index: 8;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 8px 12px;
  max-width: 280px;
  background: linear-gradient(180deg, #243254, #16203a);
  color: #fff;
  border-radius: 10px;
  box-shadow: 0 10px 26px rgba(19, 33, 68, .28);
  font-size: 11px;
  line-height: 1.4;
  text-align: center;
  /* long names wrap instead of running out of the bubble */
  white-space: normal;
  overflow-wrap: break-word;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-50%) translateY(6px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.partner-item__tip::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #16203a;
}
.partner-item__tip-role {
  color: rgba(255, 255, 255, .7);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.partner-item__tip-grant {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 600;
  color: #fff;
}
.partner-item__link:hover .partner-item__tip,
.partner-item__link:focus-visible .partner-item__tip {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

/* on a single row the first and the last mark sit close to the edge of the
   screen: their tooltip is aligned with the mark instead of being centred */
.partner-item:first-child .partner-item__tip {
  left: 0;
  transform: translateX(0) translateY(6px);
}
.partner-item:first-child .partner-item__link:hover .partner-item__tip,
.partner-item:first-child .partner-item__link:focus-visible .partner-item__tip {
  transform: translateX(0) translateY(0);
}
.partner-item:first-child .partner-item__tip::after { left: 26px; }
.partner-item:last-child .partner-item__tip {
  left: auto;
  right: 0;
  transform: translateX(0) translateY(6px);
}
.partner-item:last-child .partner-item__link:hover .partner-item__tip,
.partner-item:last-child .partner-item__link:focus-visible .partner-item__tip {
  transform: translateX(0) translateY(0);
}
.partner-item:last-child .partner-item__tip::after { left: auto; right: 26px; }

/* touch screens have no hover: the tip would only overflow the narrow
   columns, so it stays hidden there */
@media (hover: none) {
  .partner-item__tip { display: none; }
}

/* On a phone the section of the partners is a wall of marks and nothing else:
   the title of the section and the names under the marks step out of the sight.
   The marks carry the meaning on their own, and every link still names its
   organisation for a reader who does not see the picture.
   The marks stand in two columns - a cell is wide enough for the long banner
   of the faculty - and every mark sits in a slot of one height, so that the
   three rows read as three even lines. */
@media (max-width: 760px) {
  /* the hidden title stays inside the section */
  #partners { position: relative; }
  #partners .section__head {
    /* the title keeps its place for a screen reader, it is only taken out of
       the sight */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .partner-item__caption { display: none; }
  .partner-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px 16px;
    padding: 0;
  }
  .partner-item { gap: 0; }
  .partner-item__logo {
    /* one height for every mark. The seal of the university keeps a little of
       its own size, so that it does not look smaller than the marks around
       it; the zoom of the banner does not fit in a cell and is left out. */
    height: calc(32px * min(var(--partner-scale, 1), 1.2));
  }
  .partner-item__logo img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: contain;
  }
}

.partner-item__caption {
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
  text-align: center;
  overflow-wrap: break-word;
  word-break: normal;
}

