/* ============================================================================
   MOUFTOOLS — "Liquid Glass over a Sunset Sea"

   Apple-"Liquid-Glass"-style translucent panels (edge refraction, bright rim,
   tilt + glare) over an all-CSS sea scene — the sun glinting off the water, with
   container ships drifting across the horizon — that animates between a dark-blue
   night and a risen-sun daytime over ~2.5s.

   Progressive enhancement (never looks broken):
     A  Chromium  — full glass + real SVG edge refraction (gated by app.js)
     B  Safari/FF — full glass, no refraction (still premium frosted glass)
     C  no backdrop-filter / reduced-transparency / forced-colors — solid tints
   Motion honours prefers-reduced-motion; the theme swap is instant under it.
   ============================================================================ */

:root {
  /* --- Scene: dusk / sunset over the sea (dark, default) --- */
  --horizon: #ffd79a;
  --sun-core: #fff4d6;
  --sun-glow: #ffb057;
  --dune-1: #223052;  /* farthest sea band — dark twilight blue */
  --dune-2: #14203c;
  --dune-3: #0a1224;  /* nearest sea band — near-black navy */
  --grain-opacity: 0.05;
  --day-opacity: 0;   /* cross-fade weight of the daytime sky */
  --sun-rise: 14vh;   /* set low, mostly below the horizon at night */
  --sun-bright: 0.9;
  --sun-sat: 1;
  --sun-scale: 1;
  --sunpath-op: 0.34;              /* sun's reflection on the water — faint ember at night */
  --sunpath-core: rgba(255, 214, 150, 0.9);
  --sunpath-glow: rgba(255, 150, 70, 0.5);

  /* text set directly on the scene (hero, footer) */
  --scene-text: #ffffff;
  --scene-text-2: #fdf4ec;
  --scene-shadow: 0 2px 40px rgba(60, 16, 40, 0.45), 0 1px 3px rgba(40, 10, 30, 0.35);

  /* --- Glass material — DARK NAVY & very transparent (night mode) --- */
  --glass-tint:        rgba(10, 12, 28, 0.42);      /* dark navy, see-through */
  --glass-tint-strong: rgba(10, 12, 28, 0.6);       /* dock / dense chrome    */
  --glass-solid:       #14172e;                     /* Tier-C opaque          */
  --glass-blur: 28px;
  --glass-sat:  1.7;
  --glass-rim:  rgba(255, 255, 255, 0.9);
  --glass-shadow: 0 16px 44px -16px rgba(16, 5, 14, 0.6);
  --glass-radius: 24px;
  --refract-scale: 26;
  --chip-light: linear-gradient(150deg, #fffdfb, #f0e7de);
  --chip-glass: linear-gradient(150deg, rgba(250, 246, 242, 0.92), rgba(238, 229, 220, 0.84));

  /* text ON glass panels — theme-aware (light on the dark glass here) */
  --glass-text:       #fbf1ea;
  --glass-text-muted: #d0bfc7;
  --glass-accent:     #ff9a52;
  --card-text-shadow: 0 1px 14px rgba(0, 0, 0, 0.55);

  /* fixed dark — the app-icon chips stay light in both themes */
  --text-on-light: #2b1622;
  --accent-strong: #c6491a;
  --accent:        #ff8a3d;
  --focus-dark:    #140c1a;
  --focus-light:   #ffe0a8;

  /* --- Form & motion --- */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
               "Inter", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Geist Mono", "JetBrains Mono", Menlo, monospace;
  --ease: cubic-bezier(0.22, 0.61, 0.24, 1);   /* snappy — for hover/UI */
  --dur:  200ms;
  --theme-dur: 2500ms;
  --theme-ease: cubic-bezier(0.42, 0, 0.58, 1); /* gentle ease-in-out — day/night */
  --maxw: 1120px;

  --mx: 50%; --my: 0%;              /* static sheen position */
  --px: 0;   --py: 0; --sy: 0;      /* parallax */
  color-scheme: dark;
}

/* --- Daytime: sun risen, pale-blue sky, bright sunlit sea --- */
[data-theme="light"] {
  --horizon: #fbe6c4;
  --dune-1: #4aa6c4;  /* sunlit sea — lightest near the horizon */
  --dune-2: #2b83a8;
  --dune-3: #1a6188;  /* deeper foreground water */
  --grain-opacity: 0.035;
  --day-opacity: 1;
  --sun-rise: -58vh;   /* risen high into the sky */
  --sun-bright: 1.5;   /* much whiter */
  --sun-sat: 0.26;
  --sun-scale: 0.62;   /* tighter midday disk */
  --sunpath-op: 0.55;              /* brighter, whiter glitter by day */
  --sunpath-core: rgba(255, 252, 240, 0.95);
  --sunpath-glow: rgba(255, 238, 200, 0.55);

  --scene-text: #163040;
  --scene-text-2: #375265;
  --scene-shadow: 0 1px 18px rgba(255, 255, 255, 0.6);

  /* LIGHT glass — the warm-white tint, made more transparent, with dark text */
  --glass-tint:        rgba(253, 248, 243, 0.34);
  --glass-tint-strong: rgba(253, 248, 243, 0.55);
  --glass-solid:       #efe6dc;
  --glass-shadow:      0 16px 44px -16px rgba(45, 12, 34, 0.35);
  --glass-text:        #2b1622;
  --glass-text-muted:  #3a2430;
  --glass-accent:      #c6491a;
  --card-text-shadow:  0 1px 10px rgba(255, 253, 250, 0.5);
  color-scheme: light;
}

/* ---------------------------------------------------------------------------
   Base
   --------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* Hide the scrollbar entirely. Scrolling itself is untouched — wheel, trackpad,
   touch, keyboard and the scrollbar's own accessibility semantics all still
   work; only the visual track is gone. */
html, body { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }

body {
  margin: 0;
  min-height: 100vh;
  background: #0a0f24;
  color: var(--glass-text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: background-color var(--theme-dur) var(--theme-ease);
}
[data-theme="light"] body { background: #cfe6f2; }

.skip-link {
  position: fixed;
  top: -60px; left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  background: var(--glass-solid);
  color: var(--glass-text);
  font: 600 0.85rem/1 var(--font-sans);
  text-decoration: none;
  box-shadow: var(--glass-shadow);
  transition: top var(--dur) var(--ease);
}
.skip-link:focus-visible { top: 14px; outline: 2px solid var(--glass-accent); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   Scene — fixed, all-CSS, animates dusk <-> day (decorative)
   --------------------------------------------------------------------------- */
.scene { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }

/* two stacked skies, cross-faded by --day-opacity */
.scene__sky {  /* night — dark-blue twilight, only a faint warm ember at the horizon */
  position: absolute; inset: -2% 0 0 0;
  background: linear-gradient(180deg,
    #060a1c 0%, #101a48 24%, #22285e 46%, #37356a 64%, #4f4468 82%, #6e5560 100%);
}
.scene__sky--day {
  background: linear-gradient(180deg,
    #3f8fc4 0%, #6fb0d8 24%, #a6d2e6 46%, #d9ecec 66%, #f2efe0 84%, #fbe6c4 100%);
  opacity: var(--day-opacity);
  transition: opacity var(--theme-dur) var(--theme-ease);
}

/* sun: outer layer handles the theme "rise" (transition), inner handles parallax */
.sun-layer {
  position: absolute;
  left: 50%; bottom: 20%;
  width: 52vmax; height: 52vmax;
  margin-left: -26vmax; margin-bottom: -26vmax;
  transform: translateY(var(--sun-rise)) scale(var(--sun-scale));
  transition: transform var(--theme-dur) var(--theme-ease);
}
.scene__sun {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle,
    var(--sun-core) 0%, var(--sun-glow) 16%,
    rgba(255, 150, 70, 0.35) 34%, rgba(255, 130, 60, 0) 62%);
  filter: brightness(var(--sun-bright)) saturate(var(--sun-sat));
  transform: translate3d(calc(var(--px) * 16px), calc(var(--py) * 12px + var(--sy) * 22px), 0);
  transition: filter var(--theme-dur) var(--theme-ease);
  will-change: transform;
}

.scene__horizon {
  position: absolute; left: 0; right: 0; bottom: 14%;
  height: 22%;
  background: radial-gradient(120% 100% at 50% 100%,
    rgba(255, 226, 170, 0.5), rgba(255, 210, 150, 0) 70%);
  filter: blur(6px);
  opacity: calc(0.32 + var(--day-opacity) * 0.42); /* fainter/cooler at night */
  transition: opacity var(--theme-dur) var(--theme-ease);
}

.dune {
  position: absolute; left: -2%; right: -2%; width: 104%; bottom: 0; display: block;
  will-change: transform;
}
.dune path { transition: fill var(--theme-dur) var(--theme-ease); }
.dune--far  { height: 34vh; z-index: 1; transform: translate3d(calc(var(--px) * 4px),  calc(var(--sy) * 6px),  0); }
.dune--mid  { height: 26vh; z-index: 2; transform: translate3d(calc(var(--px) * 8px),  calc(var(--sy) * 12px), 0); }
.dune--near { height: 18vh; z-index: 3; transform: translate3d(calc(var(--px) * 14px), calc(var(--sy) * 20px), 0); }

/* Container ships (built by app.js) sail on the horizon, BEHIND the water bands
   (z-index below the dunes) so the wave crests in front hide their waterline.
   The layer carries .dune--far's exact parallax, so the ships stay pinned to
   the water they sit behind — scrolling moves them together. */
.scene__ships {
  position: absolute; left: 0; right: 0; bottom: 0; height: 0; z-index: 0;
  transform: translate3d(calc(var(--px) * 4px), calc(var(--sy) * 6px), 0);
}
/* Each ship's SVG (viewBox 320x260) puts the coloured-hull / black-hull seam at
   y=92 — i.e. 52.5% of the element's width above its bottom edge. Anchoring on
   that seam parks every ship on the same waterline whatever its size, while the
   black hull runs on down to y=260, far below the lowest wave, so the bottom
   edge can never surface. */
.ship {
  position: absolute; left: 0;
  width: var(--ship-w, 300px);
  bottom: calc(var(--ship-line, 20.5vh) - 0.525 * var(--ship-w));
  will-change: transform;
}
.ship > svg { display: block; width: 100%; height: auto; }

/* Sun's reflection ON the water. The wrapper is sized and transformed exactly
   like .dune--far and masked to that same wave path, so the glitter is clipped
   to the sea's surface (never floating in the sky) and rides with the water on
   scroll. The ::before holds the actual glitter column, faded out by its own
   radial mask. Two independent masks — no mask-compositing needed. */
.scene__sunpath {
  position: absolute; left: -2%; right: -2%; width: 104%; bottom: 0; height: 34vh;
  z-index: 3;                                     /* after .dune--near in the DOM → on top */
  opacity: var(--sunpath-op);
  mix-blend-mode: screen;
  transform: translate3d(calc(var(--px) * 4px), calc(var(--sy) * 6px), 0);  /* matches .dune--far */
  transition: opacity var(--theme-dur) var(--theme-ease);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'%3E%3Cpath d='M0,142 C240,92 430,150 720,120 C1020,88 1210,150 1440,112 L1440,320 L0,320 Z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'%3E%3Cpath d='M0,142 C240,92 430,150 720,120 C1020,88 1210,150 1440,112 L1440,320 L0,320 Z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
}
.scene__sunpath::before {
  content: "";
  position: absolute; left: 50%; width: 22vmax; margin-left: -11vmax;
  top: 26%; height: 74%;                          /* starts around the wave crest */
  background:
    repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0 2px, rgba(255, 255, 255, 0) 2px 9px),
    linear-gradient(180deg, var(--sunpath-core) 0%, var(--sunpath-glow) 30%, rgba(255, 255, 255, 0) 88%);
  -webkit-mask: radial-gradient(46% 118% at 50% 0%, #000 18%, rgba(0, 0, 0, 0) 80%);
          mask: radial-gradient(46% 118% at 50% 0%, #000 18%, rgba(0, 0, 0, 0) 80%);
  filter: blur(1.5px);
}

.scene__grain {
  position: absolute; inset: 0; z-index: 4;
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;
  transition: opacity var(--theme-dur) var(--theme-ease);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
   Liquid-glass material
   --------------------------------------------------------------------------- */
.glass {
  position: relative;
  isolation: isolate;
  border-radius: var(--glass-radius);
  background: var(--glass-tint);
  box-shadow:
    var(--glass-shadow),
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    inset 0 -12px 26px -18px rgba(90, 30, 50, 0.4);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: var(--glass-tint);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}
/* Chromium-only edge refraction, opted in by app.js */
[data-refract="on"] .glass {
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#liquidGlass);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#liquidGlass);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: var(--glass-solid); }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .glass {
    background: var(--glass-solid) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}
@media (forced-colors: active) {
  .glass { background: Canvas !important; border: 1px solid CanvasText; }
}

/* bright lensing rim (cross-browser, no JS) */
.glass::before {
  content: "";
  position: absolute; inset: 0; z-index: 2;
  border-radius: inherit;
  padding: 1.4px;
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.95),
    rgba(255, 255, 255, 0.25) 30%,
    rgba(255, 255, 255, 0) 52%,
    rgba(255, 255, 255, 0.5) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  pointer-events: none;
}

/* subtle static top sheen (dynamic glare on cards comes from VanillaTilt) */
.glass::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  border-radius: inherit;
  background: radial-gradient(150px 110px at var(--mx) var(--my),
    rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 65%);
  mix-blend-mode: screen;
  opacity: 0.4;
  pointer-events: none;
}

.glass > * { position: relative; z-index: 1; }

/* VanillaTilt glare sits below the content so text stays crisp */
.card .js-tilt-glare { z-index: 0 !important; border-radius: inherit; }

/* ---------------------------------------------------------------------------
   Floating dock
   --------------------------------------------------------------------------- */
.dock {
  position: fixed; top: 16px; left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex; align-items: center;
  gap: clamp(0.6rem, 2.5vw, 1.5rem);
  max-width: calc(100vw - 24px);
  padding: 0.45rem 0.55rem 0.45rem 1.15rem;
  border-radius: 999px;
  background: var(--glass-tint-strong);
}
.dock__brand {
  font-weight: 700; letter-spacing: -0.02em; font-size: 1rem;
  color: var(--glass-text); text-decoration: none; white-space: nowrap;
}
.dock__brand .dot { color: var(--glass-accent); }
.dock__nav { display: flex; align-items: center; gap: clamp(0.4rem, 2vw, 1rem); }
.dock__link {
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.01em;
  color: var(--glass-text-muted); text-decoration: none;
  padding: 0.35rem 0.5rem; border-radius: 999px;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.dock__link:hover { color: var(--glass-text); background: color-mix(in srgb, var(--glass-text) 16%, transparent); }
.dock__link:focus-visible {
  outline: none; color: var(--glass-text);
  box-shadow: 0 0 0 2px var(--focus-dark), 0 0 0 4px var(--focus-light);
}
@media (max-width: 560px) { .dock__nav .dock__link--optional { display: none; } }

/* theme toggle (day/night) */
.theme-toggle {
  flex: none;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: none;
  border-radius: 999px;
  background: color-mix(in srgb, var(--glass-text) 16%, transparent);
  color: var(--glass-text);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.theme-toggle:hover { background: color-mix(in srgb, var(--glass-text) 28%, transparent); }
.theme-toggle:active { transform: scale(0.94); }
.theme-toggle:disabled { cursor: default; }
.theme-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--focus-dark), 0 0 0 4px var(--focus-light);
}
.theme-toggle svg { width: 20px; height: 20px; display: block; }
.theme-toggle .icon-moon { display: none; }
[data-theme="light"] .theme-toggle .icon-sun  { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: block; }

/* ---------------------------------------------------------------------------
   Layout container + hero
   --------------------------------------------------------------------------- */
.wrap {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin: 0 auto;
  padding: 0 clamp(1.1rem, 5vw, 2.5rem) clamp(3rem, 8vw, 5rem);
}

.masthead {
  min-height: clamp(40vh, 50vh, 560px);
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  padding: clamp(4.5rem, 11vh, 8rem) 0 clamp(0.75rem, 2vh, 1.5rem);
  transform: translate3d(0, calc(var(--sy) * -18px), 0);
  will-change: transform;
}
.eyebrow {
  margin: 0 0 1rem;
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--scene-text-2);
  text-shadow: var(--scene-shadow);
  transition: color var(--theme-dur) var(--theme-ease), text-shadow var(--theme-dur) var(--theme-ease);
}
.wordmark {
  margin: 0;
  font-size: clamp(3rem, 11vw, 8rem);
  font-weight: 700; letter-spacing: -0.045em; line-height: 0.92;
  color: var(--scene-text);
  text-shadow: var(--scene-shadow);
  transition: color var(--theme-dur) var(--theme-ease), text-shadow var(--theme-dur) var(--theme-ease);
}
.wordmark .dot { color: var(--accent); text-shadow: 0 0 30px rgba(255, 138, 61, 0.6); }
.tagline {
  margin: 1.4rem 0 0; max-width: 40ch;
  font-size: clamp(1.05rem, 2.4vw, 1.35rem); line-height: 1.5;
  color: var(--scene-text-2); text-shadow: var(--scene-shadow);
  transition: color var(--theme-dur) var(--theme-ease), text-shadow var(--theme-dur) var(--theme-ease);
}

/* On phones the tall centred hero leaves dead space above the first card;
   size it to its content and top-align it instead. */
@media (max-width: 640px) {
  .masthead {
    min-height: auto;
    justify-content: flex-start;
    padding-top: clamp(6rem, 20vh, 8.5rem);
    padding-bottom: clamp(0.6rem, 1.6vh, 1rem);
  }
}

/* ---------------------------------------------------------------------------
   Tool grid — one column on phones, two columns on desktop.
   Tiles in a row stretch to equal height so each shows its full blurb.
   --------------------------------------------------------------------------- */
.grid {
  --grid-gap: clamp(0.85rem, 2vw, 1.35rem);
  list-style: none; margin: 0 auto; padding: 0;
  max-width: 780px;
  display: grid; grid-template-columns: 1fr; gap: var(--grid-gap);
}
@media (min-width: 640px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* With an odd number of tiles the last one would hang off to the left; centre
     it at one column's width instead so the grid stays balanced. */
  .grid > li:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    justify-self: center;
    width: calc(50% - var(--grid-gap) / 2);
  }
}
/* On phones, inset the single column so the tiles are smaller and sit in more
   open space. Padding on the grid alone, so the hero and footer above and below
   keep their existing alignment. */
@media (max-width: 639.98px) {
  .grid { padding-inline: clamp(1.25rem, 8vw, 3rem); }
}
.grid > li { min-width: 0; container-type: inline-size; display: grid; }

/* ---------------------------------------------------------------------------
   Card (glass tile). Tilt + glare are applied by VanillaTilt (app.js).
   --------------------------------------------------------------------------- */
.card {
  width: 100%;
  display: flex; flex-direction: column;
  overflow: hidden;                  /* the banner image meets the rounded edges */
  color: var(--glass-text);
  text-shadow: var(--card-text-shadow); /* legibility over the transparent glass */
  text-decoration: none;
  transform-style: preserve-3d;
  transition: box-shadow var(--dur) var(--ease), opacity 520ms var(--ease);
}
a.card { cursor: pointer; }
a.card:hover, a.card:focus-visible {
  box-shadow:
    0 30px 66px -22px rgba(45, 12, 34, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    inset 0 -12px 26px -18px rgba(90, 30, 50, 0.4);
}
a.card:focus-visible {
  outline: 2px solid transparent; outline-offset: 2px;
  box-shadow:
    0 0 0 2px var(--focus-dark),
    0 0 0 5px var(--focus-light),
    0 30px 66px -22px rgba(45, 12, 34, 0.6);
}

/* ---------------------------------------------------------------------------
   Card banner (top) — a wide image band; the logo is the hero of the tile
   --------------------------------------------------------------------------- */
.card__banner {
  position: relative;
  flex: none; width: 100%; aspect-ratio: 16 / 10;   /* a fixed banner band */
  display: grid; place-items: center;
  overflow: hidden;
  background: var(--chip-light);
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}
.card__banner img, .card__banner svg {
  width: 100%; height: 100%;
  object-fit: contain;
  object-position: center;
  padding: clamp(0.85rem, 7%, 2rem);
  display: block;
}

/* per-logo banner backgrounds */
.banner--fill { background: #010807; }                                   /* BERMUDA ships its own dark bg */
.banner--light { background: linear-gradient(160deg, #fffdfb, #efe6dd); } /* Starcores */
.banner--gem { background: radial-gradient(120% 120% at 30% 18%, #0c3b30, #04120e); }
.banner--gem svg { padding: clamp(0.6rem, 14%, 2.4rem); }

/* ---------------------------------------------------------------------------
   Card body (below the banner) — name, function, full blurb, action.
   It grows to fit the whole blurb; row-mates stretch to match the tallest.
   --------------------------------------------------------------------------- */
.card__body {
  flex: 1 1 auto;
  display: flex; flex-direction: column; gap: clamp(0.25rem, 1.4cqi, 0.55rem);
  padding: clamp(0.95rem, 5cqi, 1.5rem);
}
.name-row { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.name {
  margin: 0;
  font-size: clamp(0.98rem, 7cqi, 1.3rem);
  font-weight: 640; letter-spacing: -0.02em; line-height: 1.14;
  color: var(--glass-text);
}
.index { flex: none; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.06em; color: var(--glass-text-muted); }
.fn { margin: 0; font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.01em; color: var(--glass-text-muted); }
/* The full blurb is always shown — the card grows to fit it. */
.desc {
  margin: 0; font-size: clamp(0.82rem, 0.9vw, 0.9rem); line-height: 1.45; color: var(--glass-text-muted);
}
.action {
  margin-top: auto; padding-top: 0.5rem;
  font-family: var(--font-mono); font-size: 0.8rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--glass-text);
  display: inline-flex; align-items: center; gap: 0.4em;
}
.action .arrow { color: var(--glass-accent); transition: transform var(--dur) var(--ease); }
a.card:hover .action .arrow, a.card:focus-visible .action .arrow { transform: translate(2px, -2px); }
a.card:hover .action .arrow--right, a.card:focus-visible .action .arrow--right { transform: translateX(3px); }
a.card:hover .action .arrow--down,  a.card:focus-visible .action .arrow--down  { transform: translateY(3px); }

/* Inert card (PDFproc) */
.card.inert { opacity: 0.62; cursor: default; }
.card.inert::before { opacity: 0.5; }
.card.inert .action { color: var(--glass-text-muted); }
.card.inert .card__banner { opacity: 0.8; }

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */
.footer {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin: clamp(3rem, 8vw, 5rem) auto 0;
  padding: 1rem clamp(1.1rem, 5vw, 2.5rem) clamp(2rem, 6vw, 3rem);
  color: var(--scene-text-2); font-size: 0.85rem;
  text-shadow: var(--scene-shadow);
  transition: color var(--theme-dur) var(--theme-ease), text-shadow var(--theme-dur) var(--theme-ease);
}
.footer p { margin: 0; }
.footer a { color: var(--scene-text-2); text-decoration: none; border-bottom: 1px solid currentColor; }
.footer a:hover { color: var(--accent); }
.footer a:focus-visible {
  outline: none; border-radius: 3px;
  box-shadow: 0 0 0 2px var(--focus-dark), 0 0 0 4px var(--focus-light);
}

/* ---------------------------------------------------------------------------
   Back link (mods page)
   --------------------------------------------------------------------------- */
.backlink {
  display: inline-flex; align-items: center; gap: 0.45em;
  margin: clamp(5.5rem, 12vh, 7rem) 0 0;
  padding: 0.5rem 0.95rem; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.8rem;
  color: var(--glass-text); text-decoration: none;
}
.backlink .arrow { transition: transform var(--dur) var(--ease); }
.backlink:hover .arrow { transform: translateX(-3px); }
.backlink:focus-visible {
  outline: 2px solid transparent;
  box-shadow: 0 0 0 2px var(--focus-dark), 0 0 0 5px var(--focus-light);
}
.masthead--sub { min-height: 0; padding-top: clamp(1.5rem, 5vh, 3rem); }

/* ---------------------------------------------------------------------------
   Entrance — opacity fade (own slot; never touches transform)
   --------------------------------------------------------------------------- */
[data-reveal="on"] .card { opacity: 0; }
[data-reveal="on"] li.in-view .card { opacity: 1; }
[data-reveal="on"] li.in-view .card.inert { opacity: 0.62; }

/* ---------------------------------------------------------------------------
   Theme change — while the .theming class is on <html> (added by app.js for the
   transition's duration), the glass tint and on-glass text/shadow colours ease
   between dark and light over the full --theme-dur. Normal hover transitions
   stay fast the rest of the time.
   --------------------------------------------------------------------------- */
html.theming .glass,
html.theming .card,
html.theming .name, html.theming .fn, html.theming .desc, html.theming .index,
html.theming .action, html.theming .action .arrow,
html.theming .dock__brand, html.theming .dock__brand .dot, html.theming .dock__link,
html.theming .theme-toggle, html.theming .backlink, html.theming .skip-link {
  transition:
    color var(--theme-dur) var(--theme-ease),
    background-color var(--theme-dur) var(--theme-ease),
    text-shadow var(--theme-dur) var(--theme-ease),
    box-shadow var(--theme-dur) var(--theme-ease) !important;
}

/* ---------------------------------------------------------------------------
   Reduced motion — no parallax/tilt/entrance; theme swap is instant
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
  .scene__sun, .dune, .masthead, .sun-layer, .scene__sunpath { transform: none !important; }
  [data-reveal="on"] .card { opacity: 1 !important; }
  [data-reveal="on"] .card.inert { opacity: 0.62 !important; }
}
