/* ============================================================
   CSEE Analytical Platforms — landing & login
   ============================================================ */

/* ---------- tokens ---------- */
:root {
  --ink:        #10151f;
  --ink-soft:   #46506180;
  --ink-mute:   #5b6779;
  --paper:      #ffffff;
  --paper-dim:  #f5f7fb;
  --line:       #e3e8f0;

  --primary:    rgb(97, 122, 194);
  --primary-rgb: 97, 122, 194;
  --tint-rgb:   230, 240, 255;

  --shell:      min(1240px, 92vw);
  --radius:     18px;
  --radius-sm:  11px;

  --ease:       cubic-bezier(.22, .61, .36, 1);
  --shadow:     0 1px 2px rgba(16,21,31,.05), 0 12px 32px -12px rgba(16,21,31,.16);
  --shadow-lg:  0 2px 4px rgba(16,21,31,.06), 0 32px 64px -24px rgba(16,21,31,.28);

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* platform theming — set on any ancestor */
[data-platform] { --primary: rgb(var(--primary-rgb)); }
[data-platform="proptech"]   { --primary-rgb:  97, 122, 194; --tint-rgb: 230, 240, 255; }
[data-platform="energytech"] { --primary-rgb:  40, 120, 120; --tint-rgb: 180, 235, 225; }
[data-platform="watermngt"]  { --primary-rgb:  20,  95, 160; --tint-rgb: 190, 220, 245; }
[data-platform="esg"]        { --primary-rgb:  46, 125,  50; --tint-rgb: 205, 232, 207; }
[data-platform="contech"]    { --primary-rgb: 130, 100,  60; --tint-rgb: 210, 170, 109; }

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

html {
  scroll-behavior: smooth;
  /* Firefox: the thumb carries the colour of whatever section you are in */
  scrollbar-width: thin;
  scrollbar-color: rgb(var(--primary-rgb)) rgba(16, 21, 31, .07);
}

/* WebKit: the track carries the whole page's colour run, built from the real
   section positions in site.js — so wherever the bar sits, it is the colour
   of the section behind it. The thumb is translucent, letting it show. */
::-webkit-scrollbar { width: 12px; }
::-webkit-scrollbar-track { background: var(--scroll-track, var(--paper-dim)); }
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .6);
  background-clip: content-box;
  border: 3px solid transparent;
  border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, .88);
  background-clip: content-box;
}

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* `clip` rather than `hidden`: hidden turns the body into a scroll
     container, which silently breaks every position:sticky on the page. */
  overflow-x: clip;
}

img { max-width: 100%; display: block; }
/* the line above outranks the browser's own [hidden] rule, which would
   otherwise hide an image — without this, anything marked hidden still
   renders. Keep it after every display declaration. */
[hidden] { display: none !important; }
a { color: inherit; }

h1, h2, h3 { margin: 0; line-height: 1.08; letter-spacing: -.022em; font-weight: 700; }
p  { margin: 0; line-height: 1.62; }

.shell { width: var(--shell); margin-inline: auto; }
.nowrap { white-space: nowrap; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- buttons ---------- */
.btn {
  --btn-bg: var(--primary);
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  padding: .82em 1.5em;
  font: inherit; font-weight: 600; font-size: .935rem; letter-spacing: -.005em;
  border: 1px solid transparent; border-radius: 100px;
  text-decoration: none; cursor: pointer;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease),
              background-color .2s var(--ease), color .2s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }

.btn--primary { background: var(--btn-bg); color: #fff; box-shadow: 0 8px 20px -8px rgba(var(--primary-rgb), .7); }
.btn--primary:hover { box-shadow: 0 14px 30px -10px rgba(var(--primary-rgb), .8); }

.btn--ghost { background: transparent; color: var(--primary); border-color: rgba(var(--primary-rgb), .34); }
.btn--ghost:hover { background: rgba(var(--primary-rgb), .07); border-color: rgba(var(--primary-rgb), .55); }

.btn--light { background: rgba(255,255,255,.14); color: #fff; border-color: rgba(255,255,255,.4); backdrop-filter: blur(8px); }
.btn--light:hover { background: rgba(255,255,255,.24); }

.btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.btn__arrow { transition: transform .25s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(3px); }

/* ---------- top bar ---------- */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  width: var(--shell); margin-inline: auto; padding: 1.1rem 0;
  transition: padding .3s var(--ease);
}
.topbar::before {
  content: ''; position: absolute; inset: -1.1rem -50vw;
  background: rgba(255,255,255,.82); backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--line);
  opacity: 0; transition: opacity .3s var(--ease); pointer-events: none;
}
.topbar.is-stuck::before { opacity: 1; }
.topbar > * { position: relative; }
.topbar__brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; font-weight: 700; letter-spacing: -.02em; }
.topbar__brand img { height: 34px; width: auto; }
.topbar__nav { display: flex; align-items: center; gap: 1.6rem; }
/* :not(.btn) matters — without it this outranks .btn--primary's own colour
   and leaves the Login button with grey text on a coloured pill */
.topbar__nav a:not(.btn) {
  text-decoration: none; font-size: .9rem; font-weight: 500;
  color: var(--ink-mute); transition: color .25s var(--ease);
}
.topbar__nav a:not(.btn):hover { color: var(--ink); }

/* Once the bar has a solid background it picks up the colour of whichever
   platform is on screen. The brand hue is mixed toward ink so the smaller
   text keeps its contrast on white; browsers without color-mix fall back to
   the muted grey set above. */
.topbar.is-stuck .topbar__nav a:not(.btn) {
  color: color-mix(in srgb, rgb(var(--primary-rgb)) 72%, #0f1420);
}
.topbar.is-stuck .topbar__nav a:not(.btn):hover {
  color: color-mix(in srgb, rgb(var(--primary-rgb)) 96%, #0f1420);
}
.topbar.is-stuck .topbar__brand { color: color-mix(in srgb, rgb(var(--primary-rgb)) 60%, #0f1420); }
.topbar .btn--primary { transition: background-color .25s var(--ease), box-shadow .25s var(--ease); }

/* light treatment while floating over the hero */
.topbar:not(.is-stuck) .topbar__brand { color: #fff; }
.topbar:not(.is-stuck) .topbar__nav a:not(.btn) { color: rgba(255,255,255,.78); }
.topbar:not(.is-stuck) .topbar__nav a:not(.btn):hover { color: #fff; }
.topbar:not(.is-stuck) .topbar__nav .btn--primary {
  background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.42);
  backdrop-filter: blur(8px); box-shadow: none;
}
.topbar:not(.is-stuck) .topbar__nav .btn--primary:hover { background: rgba(255,255,255,.26); }
@media (max-width: 860px) { .topbar__nav a:not(.btn) { display: none; } }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative; min-height: 100svh;
  display: grid; place-items: center;
  overflow: hidden; isolation: isolate;
  color: #fff;
}
.hero__backdrops {
  position: absolute; inset: -12% 0 -12% 0; z-index: -2;
  will-change: transform;
}
/* one layer per slide; a slide with no photograph shows its platform colour.
   Same weighting as the PropTech section below: the photograph reads
   largest on the left, behind the copy, and stays open and untinted on the
   right where a platform's own graphic can show through later. */
.hero__bg {
  position: absolute; inset: 0;
  background-color: rgb(var(--primary-rgb));
  background-position: left center; background-size: cover; background-repeat: no-repeat;
  opacity: 0; transition: opacity .9s var(--ease);
}
.hero__bg.is-active { opacity: 1; }
.hero__bg::after {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 18% 20%, rgba(var(--primary-rgb), .5), transparent 62%),
    linear-gradient(100deg, rgba(8,13,26,.72) 0%, rgba(8,13,26,.5) 45%, rgba(8,13,26,.22) 100%),
    linear-gradient(180deg, rgba(8,13,26,.5) 0%, rgba(8,13,26,.3) 45%, rgba(8,13,26,.78) 100%);
}

.hero__inner { width: var(--shell); padding: 9rem 0 6rem; }

/* slides stack in one grid cell, so the container takes the height of the
   tallest slide and never rides over the dots below it */
.hero__slides { display: grid; }
.hero__slide {
  grid-area: 1 / 1;
  opacity: 0; visibility: hidden;
  transform: translateY(18px);
  transition: opacity .8s var(--ease), transform .8s var(--ease), visibility .8s;
}
.hero__slide.is-active { opacity: 1; visibility: visible; transform: none; }

.hero__kicker {
  display: inline-flex; align-items: center; gap: .6rem;
  font-size: .78rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255,255,255,.82); margin-bottom: 1.4rem;
}
.hero__kicker::before { content: ''; width: 30px; height: 1px; background: currentColor; }

.hero__title { font-size: clamp(2.6rem, 6.4vw, 5rem); letter-spacing: -.04em; }
.hero__sub {
  max-width: 46ch; margin-top: 1.5rem;
  font-size: clamp(1rem, 1.35vw, 1.175rem); color: rgba(255,255,255,.8);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2.4rem; }

.hero__dots { display: flex; gap: .55rem; margin-top: 3rem; }
.hero__dot {
  width: 34px; height: 4px; padding: 0; border: 0; border-radius: 100px;
  background: rgba(255,255,255,.28); cursor: pointer; overflow: hidden;
  transition: background .3s var(--ease);
}
.hero__dot.is-active { background: rgba(255,255,255,.75); }
.hero__dot:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.hero__scroll {
  position: absolute; left: 50%; bottom: 2.2rem; translate: -50% 0;
  display: grid; place-items: center; gap: .55rem;
  font-size: .72rem; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.6); text-decoration: none;
}
.hero__scroll span { display: block; width: 1px; height: 30px; background: linear-gradient(rgba(255,255,255,.7), transparent); animation: scroll-hint 2.1s var(--ease) infinite; }
@keyframes scroll-hint { 0%,100% { transform: scaleY(.4); transform-origin: top; opacity: .35 } 50% { transform: scaleY(1); opacity: 1 } }

/* ============================================================
   SECTION SCAFFOLD
   ============================================================ */
.band { padding: clamp(5rem, 11vw, 9rem) 0; }
.band--dim { background: var(--paper-dim); }

.band__head { max-width: 62ch; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.band__eyebrow {
  display: block; font-size: .78rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase; color: var(--primary);
  margin-bottom: .9rem;
}
.band__title { font-size: clamp(1.9rem, 3.6vw, 2.9rem); letter-spacing: -.035em; }
.band__sub { margin-top: 1.1rem; color: var(--ink-mute); font-size: 1.06rem; }

/* ============================================================
   PLATFORM CARDS
   ============================================================ */
.cards {
  display: grid; gap: 1.4rem;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}
.card {
  --primary: rgb(var(--primary-rgb));
  position: relative; display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease), border-color .4s var(--ease);
}
.card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); border-color: rgba(var(--primary-rgb), .35); }

.card__media {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  background: rgb(var(--tint-rgb));   /* shows through only if the photo fails to load */
}
/* a light brand-colour wash over the photograph, not behind it, so the
   photo itself stays the main thing the card shows */
.card__media::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(145deg,
    rgba(var(--primary-rgb), .5) 0%,
    rgba(var(--primary-rgb), .12) 55%,
    transparent 100%);
}
.card__photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: .92;
  transition: transform .7s var(--ease), opacity .4s var(--ease);
}
.card:hover .card__photo { transform: scale(1.06); opacity: .8; }

.card__badge {
  position: absolute; top: .9rem; right: .9rem; z-index: 3;
  padding: .34em .78em; border-radius: 100px;
  font-size: .68rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  background: rgba(255,255,255,.92); color: var(--primary);
  box-shadow: 0 2px 10px rgba(0,0,0,.14);
}
.card__badge--soon { background: rgba(16,21,31,.72); color: #fff; backdrop-filter: blur(6px); }

.card__body { display: flex; flex-direction: column; flex: 1; padding: 1.5rem 1.5rem 1.6rem; }
.card__name { font-size: 1.32rem; letter-spacing: -.028em; }
.card__name { flex: 1; }
/* Read more + Login, or Read more alone at full width */
.card__actions { display: flex; gap: .6rem; margin-top: 1.4rem; }
.card__actions .btn { flex: 1; padding-inline: 1em; font-size: .875rem; }

/* ============================================================
   PLATFORM SECTIONS (100vh, parallax)
   ============================================================ */
.platform {
  position: relative; min-height: 100svh;
  display: grid; align-items: center;
  overflow: hidden; isolation: isolate;
  padding: 7rem 0;
  background: rgb(var(--tint-rgb));
}
.platform__bg {
  position: absolute; inset: -14% 0; z-index: -3;
  background: rgb(var(--tint-rgb)) center/cover no-repeat;
  will-change: transform;
}
.platform__wash {
  position: absolute; inset: 0; z-index: -2;
  background:
    linear-gradient(100deg,
      rgba(var(--primary-rgb), .97) 0%,
      rgba(var(--primary-rgb), .88) 42%,
      rgba(var(--primary-rgb), .62) 74%,
      rgba(var(--primary-rgb), .46) 100%),
    linear-gradient(180deg, rgba(10,14,24,.56), rgba(10,14,24,.7));
}
.platform__scene {
  position: absolute; inset: 0; z-index: -1;
  display: grid; place-items: center;
  color: #fff;                      /* drives currentColor of the line art */
  opacity: .62; will-change: transform;
}
.platform__scene .scene { width: min(92%, 1100px); height: auto; }
/* at section scale the strokes need more weight to stay readable */
.platform__scene .scene .trace path,
.platform__scene .scene .trace line,
.platform__scene .scene .trace circle,
.platform__scene .scene .trace-circle,
.platform__scene .scene .wave { stroke-width: 2.4; }
.platform__scene .scene .hook-shape { stroke-width: 2.6; }

.platform__grid {
  display: grid; gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  align-items: center; color: #fff;
}
@media (max-width: 940px) { .platform__grid { grid-template-columns: 1fr; } }

.platform__index {
  font-size: .78rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.7);
  display: flex; align-items: center; gap: .8rem; margin-bottom: 1.3rem;
}
.platform__index::after { content: ''; flex: 1; max-width: 90px; height: 1px; background: rgba(255,255,255,.35); }

.platform__title { font-size: clamp(2.2rem, 5vw, 3.9rem); letter-spacing: -.04em; }
/* the platform's description — one <p> per paragraph from `text` */
.platform__text { margin-top: 1.5rem; max-width: 56ch; color: rgba(255,255,255,.84); }
.platform__text p + p { margin-top: .85rem; }
.platform__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2.2rem; }

/* platforms still in development: a bold line where the buttons would be */
.platform__coming {
  margin-top: 2.2rem;
  font-size: clamp(1.1rem, 1.7vw, 1.35rem); font-weight: 700; letter-spacing: -.01em;
  color: #fff;
}

/* ============================================================
   SECTION WITH A LOOPING WIREFRAME CLIP  (PropTech)
   Ordinary 100vh section — the clip just loops on its own.
   ============================================================ */

/* a soft, roughly circular glow seated over the photo rather than a hard
   diagonal split — gentler on the eye, and it still fades the same way:
   dense behind the copy on the left, open on the right around the clip */
.platform--media .platform__wash {
  background:
    radial-gradient(135% 115% at 20% 50%,
      rgba(var(--primary-rgb), .94) 0%,
      rgba(var(--primary-rgb), .74) 42%,
      rgba(var(--primary-rgb), .4) 70%,
      rgba(var(--primary-rgb), .14) 100%),
    linear-gradient(180deg, rgba(10,14,24,.36) 0%, rgba(10,14,24,.18) 100%);
}

/* The photograph is the dominant image — a tall panel down the left side of
   the section, behind the copy, its outer edge feathered so it rises out of
   the section colour instead of starting on a hard line. The wireframe clip
   sits on the right at roughly two-thirds its size — smaller, but a real
   presence rather than a tucked-away badge — and off its scale, so the two
   never read as the same building drawn twice. */
.platform--media .platform__bg {
  inset: 0 auto 0 0;
  width: var(--photo-w, 62%);
  height: 100%;
  background-position: center 32%;
  background-size: cover;
  opacity: var(--photo-o, .97);
  -webkit-mask-image: linear-gradient(to left, transparent 0, #000 24%);
          mask-image: linear-gradient(to left, transparent 0, #000 24%);
}

/* a real right-hand panel, planted flush into the section's bottom-right
   corner like the photograph is planted on the left. The clip itself is
   landscape (3:2), so the panel is shaped to that same ratio — the whole
   drawing shows edge to edge, nothing cropped off its sides. */
.platform__video {
  position: absolute; z-index: -1;
  right: 0; bottom: 0;
  width: min(86%, 1238px);
  aspect-ratio: 3 / 2;
  display: grid; place-items: center;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10%);
          mask-image: linear-gradient(180deg, transparent 0, #000 10%);
}
.media__clip, .media__still {
  grid-area: 1 / 1;          /* share one cell — the still stands in for the
                                clip, it never sits beside it */
  width: 100%; height: 100%;
  object-fit: contain;
  object-position: center bottom;
  /* the footage itself carries a wider empty margin on its right than its
     left, so centred it reads short of the screen's edge — nudged right to
     close that gap; the panel has no clip of its own, so the sliver that
     goes past the edge is simply lost off-screen, not visible anyway */
  transform: translateX(12%);
  filter: drop-shadow(0 6px 22px rgba(8, 12, 24, .4));
}
.media__still { opacity: .95; }

.media__content { max-width: min(46%, 560px); color: #fff; }
.media__content .platform__text { max-width: none; }

/* ============================================================
   MIRRORED VARIANT — clip on the left, photo + copy on the right.
   Set loopVideo.mirror: true on a platform to flip it this way; every
   rule above stays the default (PropTech, EnergyTech's own section
   still reads left-to-right the normal way unless mirrored).
   ============================================================ */
.platform--media-mirror .platform__wash {
  background:
    radial-gradient(135% 115% at 80% 50%,
      rgba(var(--primary-rgb), .94) 0%,
      rgba(var(--primary-rgb), .74) 42%,
      rgba(var(--primary-rgb), .4) 70%,
      rgba(var(--primary-rgb), .14) 100%),
    linear-gradient(180deg, rgba(10,14,24,.36) 0%, rgba(10,14,24,.18) 100%);
}
.platform--media-mirror .platform__bg {
  inset: 0 0 0 auto;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24%);
          mask-image: linear-gradient(to right, transparent 0, #000 24%);
}
.platform--media-mirror .platform__video {
  right: auto; left: 0;
  /* the same soft top edge, plus a fade on the right so a wide drawing
     (WaterMngt's dam) thins out before it reaches the copy and the Login
     button instead of running through them */
  -webkit-mask-image:
    linear-gradient(180deg, transparent 0, #000 10%),
    linear-gradient(to right, #000 50%, transparent 62%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(180deg, transparent 0, #000 10%),
    linear-gradient(to right, #000 50%, transparent 62%);
          mask-composite: intersect;
}
.platform--media-mirror .media__clip,
.platform--media-mirror .media__still { transform: translateX(-12%); }
.platform--media-mirror .media__content { margin-left: auto; }

@media (max-width: 940px) {
  .platform--media { padding: 7rem 0 5rem; }
  .platform--media .platform__bg {
    inset: 0; width: auto; height: auto;
    background-position: center 30%;
    opacity: calc(var(--photo-o, .95) * .55);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 30%);
            mask-image: linear-gradient(180deg, transparent 0, #000 30%);
  }
  .platform__video {
    position: relative; right: auto; bottom: auto; order: 2;   /* below the copy, not above it */
    width: 100%; max-width: 788px; aspect-ratio: 3 / 2; margin: 2.5rem auto 0;
    -webkit-mask-image: none; mask-image: none;
  }
  .media__clip, .media__still,
  .platform--media-mirror .media__clip,
  .platform--media-mirror .media__still { transform: none; }  /* centred in its own box, not edge-anchored */
  .platform--media-mirror .platform__video { -webkit-mask-image: none; mask-image: none; }
  .media__content { max-width: none; }
}

/* ---------- reveal on scroll ---------- */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .09s }
.reveal[data-delay="2"] { transition-delay: .18s }
.reveal[data-delay="3"] { transition-delay: .27s }
.reveal[data-delay="4"] { transition-delay: .36s }

/* ============================================================
   ANIMATED LINE-ART SCENES
   ============================================================ */
.scene { width: 100%; height: 100%; overflow: visible; }

.scene .trace path,
.scene .trace line,
.scene .trace circle,
.scene .trace-circle {
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1400; stroke-dashoffset: 1400;
  animation: trace-draw 13s var(--ease) infinite;
}
.scene .trace--slow path, .scene .trace--slow circle { animation-duration: 16s; animation-delay: 1.2s; }
/* Draws itself in, then holds for most of the loop. The dash reset happens
   only while opacity is already 0, so you never see the contour "unwind"
   into disconnected stubs — it simply fades and redraws. */
@keyframes trace-draw {
  0%       { stroke-dashoffset: 1400; opacity: 0 }
  8%       { opacity: .92 }
  38%, 88% { stroke-dashoffset: 0;    opacity: .95 }
  98%      { stroke-dashoffset: 0;    opacity: 0 }
  100%     { stroke-dashoffset: 1400; opacity: 0 }
}

/* proptech — windows */
.scene .fill-soft .lit {
  fill: currentColor; stroke: none;
  animation: win-glow 3.4s var(--ease) infinite;
}
@keyframes win-glow { 0%, 100% { opacity: .1 } 50% { opacity: .72 } }

/* energytech — turbine + sun */
.scene .spin { animation: spin 7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg) } }
.scene .blade { fill: currentColor; opacity: .8; }
.scene .hub   { fill: currentColor; }
.scene .ray {
  stroke: currentColor; stroke-width: 2; stroke-linecap: round;
  animation: ray-breathe 2.6s var(--ease) infinite;
}
@keyframes ray-breathe { 0%, 100% { opacity: .2; transform: scale(.94) } 50% { opacity: .9; transform: scale(1.06) } }
.scene .rays { transform-origin: 640px 130px; }

/* watermngt — waves, droplet, ripples */
.scene .wave {
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
  animation: wave-flow 5s linear infinite;
}
.scene .wave--2 { animation-duration: 7s;  opacity: .6; }
.scene .wave--3 { animation-duration: 9.5s; opacity: .35; }
@keyframes wave-flow { to { transform: translateX(200px) } }
.scene .waves .wave--1 { animation-name: wave-flow-1 }
@keyframes wave-flow-1 { from { transform: translate(-400px, 352px) } to { transform: translate(-200px, 352px) } }
.scene .waves .wave--2 { animation-name: wave-flow-2 }
@keyframes wave-flow-2 { from { transform: translate(-400px, 378px) } to { transform: translate(-200px, 378px) } }
.scene .waves .wave--3 { animation-name: wave-flow-3 }
@keyframes wave-flow-3 { from { transform: translate(-400px, 404px) } to { transform: translate(-200px, 404px) } }

.scene .drop { fill: currentColor; opacity: .85; }
.scene .drop-group { animation: drop-fall 3.2s var(--ease) infinite; }
@keyframes drop-fall {
  0%       { transform: translateY(0);     opacity: 0 }
  12%      { opacity: .9 }
  48%      { transform: translateY(112px); opacity: .9 }
  54%, 100%{ transform: translateY(112px); opacity: 0 }
}
.scene .ripple {
  fill: none; stroke: currentColor; stroke-width: 1.6;
  opacity: 0; animation: ripple-out 3.2s var(--ease) infinite;
}
.scene .ripple--2 { animation-delay: .22s; }
@keyframes ripple-out {
  0%, 48%  { transform: scale(.3); opacity: 0 }
  56%      { opacity: .75 }
  86%, 100%{ transform: scale(3.4); opacity: 0 }
}
.scene .ripple, .scene .ripple--2 { transform-origin: 300px 300px; transform-box: fill-box; }

/* esg — smoke */
.scene .puff {
  fill: currentColor; opacity: 0;
  animation: smoke-rise 5.4s var(--ease) infinite;
}
@keyframes smoke-rise {
  0%   { transform: translate(0, 0) scale(.35);      opacity: 0 }
  14%  { opacity: .5 }
  55%  { transform: translate(-14px, -92px) scale(1.15); opacity: .28 }
  100% { transform: translate(-34px, -190px) scale(2.1); opacity: 0 }
}
.scene .puff { transform-box: fill-box; transform-origin: center; }

/* contech — crane */
.scene .trolley-box { fill: currentColor; opacity: .85; }
.scene .trolley { animation: trolley-run 9s var(--ease) infinite; }
@keyframes trolley-run {
  0%, 8%    { transform: translateX(0) }
  30%, 62%  { transform: translateX(-150px) }
  86%, 100% { transform: translateX(0) }
}
.scene .cable { fill: currentColor; transform-origin: 469px 140px; animation: cable-drop 9s var(--ease) infinite; }
@keyframes cable-drop {
  0%, 30%   { transform: scaleY(.18) }
  44%, 56%  { transform: scaleY(1) }
  70%, 100% { transform: scaleY(.18) }
}
.scene .hook { animation: hook-drop 9s var(--ease) infinite; }
@keyframes hook-drop {
  0%, 30%   { transform: translateY(167px) }
  44%, 56%  { transform: translateY(290px) }
  70%, 100% { transform: translateY(167px) }
}
.scene .hook-shape { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.scene .load { fill: currentColor; opacity: .78; }

/* ============================================================
   LOGIN PAGE
   ============================================================ */
.login {
  min-height: 100svh;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
}
@media (max-width: 980px) { .login { grid-template-columns: 1fr; } }

.login__form-col {
  display: grid; align-content: center;
  padding: clamp(2.5rem, 6vw, 5rem) clamp(1.5rem, 6vw, 5rem);
  /* a faint wash of the platform's own tint, fading to white */
  background:
    radial-gradient(90% 70% at 0% 0%, rgba(var(--tint-rgb), .75), transparent 70%),
    linear-gradient(180deg, rgba(var(--tint-rgb), .28), var(--paper) 65%);
}
.login__form-inner { width: min(420px, 100%); margin-inline: auto; }

.login__back {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .88rem; font-weight: 500; color: var(--ink-mute);
  text-decoration: none; margin-bottom: 2.6rem;
  transition: color .2s, gap .2s var(--ease);
}
.login__back:hover { color: var(--primary); gap: .75rem; }

.login__brand { display: flex; align-items: center; gap: .7rem; margin-bottom: 1.8rem; }
.login__brand img { height: 40px; width: auto; }
.login__brand-text { font-size: .78rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--primary); }

.login__title { font-size: clamp(1.75rem, 3.2vw, 2.3rem); letter-spacing: -.035em; }
.login__lead { margin-top: .7rem; color: var(--ink-mute); font-size: .97rem; }

.field { display: grid; gap: .45rem; margin-top: 1.25rem; }
.field__label { font-size: .84rem; font-weight: 600; color: var(--ink); }
.field input {
  width: 100%; padding: .88em 1em;
  font: inherit; font-size: .96rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: border-color .2s, box-shadow .2s;
}
.field input::placeholder { color: #9aa5b6; }
.field input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 4px rgba(var(--primary-rgb), .14);
}

.login__row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.1rem; }
.login__link { font-size: .87rem; font-weight: 500; color: var(--primary); text-decoration: none; }
.login__link:hover { text-decoration: underline; }
.login__submit { width: 100%; margin-top: 1.6rem; padding-block: .95em; font-size: 1rem; }

.login__error {
  display: none; align-items: center; gap: .6rem; margin-top: 1.2rem;
  padding: .8em 1em; border-radius: var(--radius-sm);
  background: #fef2f2; border: 1px solid #fecaca; color: #b42318; font-size: .89rem;
}
.login__error.is-on { display: flex; }
/* shown by the platform app after sign-out (/login?logout) */
.login__notice {
  display: flex; align-items: center; gap: .6rem; margin-top: 1.2rem;
  padding: .8em 1em; border-radius: var(--radius-sm); font-size: .89rem;
  background: rgba(var(--primary-rgb), .07); border: 1px solid rgba(var(--primary-rgb), .25);
  color: var(--primary);
}

/* side panel — the platform's photograph under its colour, with the
   platform's name and description at the top, the same way its section
   on the landing page reads */
.login__panel {
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; align-items: start;
  padding: clamp(2.5rem, 5vw, 4.5rem) clamp(2rem, 4.5vw, 4rem);
  color: #fff; min-height: 340px;
}
.login__panel-bg { position: absolute; inset: 0; z-index: -3; background: rgb(var(--tint-rgb)) center/cover no-repeat; }
/* dense behind the copy at the top, opening up toward the bottom so the
   photograph carries the lower half */
.login__panel-wash {
  position: absolute; inset: 0; z-index: -2;
  background:
    radial-gradient(130% 90% at 15% 0%,
      rgba(var(--primary-rgb), .95) 0%,
      rgba(var(--primary-rgb), .82) 40%,
      rgba(var(--primary-rgb), .42) 75%,
      rgba(var(--primary-rgb), .22) 100%),
    linear-gradient(180deg, rgba(10,14,24,.28), rgba(10,14,24,.12));
}

.login__panel-name { font-size: clamp(1.9rem, 3.4vw, 2.8rem); letter-spacing: -.038em; line-height: 1.08; }
.login__panel-text { margin-top: 1.3rem; max-width: 50ch; color: rgba(255,255,255,.86); font-size: 1rem; }
.login__panel-text p + p { margin-top: .75rem; }
.login__panel-tag {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .75rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255,255,255,.76); margin-bottom: 1.1rem;
}
.login__panel-tag::before { content: ''; width: 26px; height: 1px; background: currentColor; }

/* switcher band under the login */
.switcher {
  padding: clamp(3.5rem, 8vw, 6rem) 0;
  background: linear-gradient(180deg, rgba(var(--tint-rgb), .45), var(--paper-dim) 70%);
  border-top: 1px solid var(--line);
}
.switcher__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-bottom: 2.4rem; }
.switcher__title { font-size: clamp(1.4rem, 2.6vw, 1.95rem); letter-spacing: -.03em; }
.switcher__sub { margin-top: .6rem; color: var(--ink-mute); font-size: .97rem; }

/* ============================================================
   FOOTER
   ============================================================ */
.footer { padding: 4rem 0 3rem; background: #0d1220; color: rgba(255,255,255,.62); }
.footer__grid { display: flex; justify-content: space-between; gap: 2.5rem; flex-wrap: wrap; }
.footer__brand { display: flex; align-items: center; gap: .8rem; color: #fff; font-weight: 700; letter-spacing: -.02em; }
.footer__brand img { height: 38px; width: auto; }
.footer__links { display: flex; gap: 2rem; flex-wrap: wrap; }
.footer__links a { text-decoration: none; font-size: .9rem; transition: color .2s; }
.footer__links a:hover { color: #fff; }
.footer__base { margin-top: 3rem; padding-top: 1.6rem; border-top: 1px solid rgba(255,255,255,.1); font-size: .83rem; }

/* ============================================================
   MOTION PREFERENCES
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .scene .trace path, .scene .trace line, .scene .trace circle, .scene .trace-circle {
    stroke-dashoffset: 0; opacity: .9;
  }
  .scene .puff, .scene .ripple { opacity: .3 }
  .reveal { opacity: 1; transform: none; }
  .hero__bg, .platform__bg, .platform__scene { transform: none !important; }
}
