/* ==========================================================================
   Design System · Components
   Every component reads only the generic theme variables (--bg, --fg, …)
   so it works inside .theme-dark, .theme-light, .theme-white, .theme-slate.
   ========================================================================== */

/* ---- 1. Site header ------------------------------------------------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-header);
  height: var(--header-h); color: var(--c-light);
  transition: background var(--dur), height var(--dur), box-shadow var(--dur), -webkit-backdrop-filter var(--dur), backdrop-filter var(--dur);
}
.site-header__inner { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6); }
.site-header__logo { display: inline-flex; }
.site-header__logo img { width: var(--logo-w); height: var(--logo-h); object-fit: contain; object-position: left; }
.site-nav { display: flex; align-items: center; gap: var(--sp-8); }
.site-nav a { position: relative; font-size: var(--fs-nav); line-height: 1.45; padding-block: var(--sp-1); transition: color var(--dur-fast); }
.site-nav a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 1px;
  background: currentColor; transition: right var(--dur) var(--ease);
}
.site-nav a:hover::after, .site-nav a:focus-visible::after { right: 0; }
.site-header.is-scrolled {
  height: 76px; background: rgba(var(--c-navy-rgb), .82);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 rgba(var(--c-light-rgb), .08);
}
/* the header on every page, as on the live project pages: no bar, a light
   logo and links blended with "difference", so they read dark over light
   sections and light over photos and dark sections */
.site-header--light { color: var(--c-white); mix-blend-mode: difference; }
.site-header--light.is-scrolled { height: var(--header-h); background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.site-header--light.is-open { mix-blend-mode: normal; }
.site-header--static { position: absolute; }
.nav-toggle { display: none; width: 44px; height: 44px; align-items: center; justify-content: center; margin-right: -10px; }
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
  display: block; width: 24px; height: 2px; background: currentColor; content: ""; position: relative;
  transition: transform var(--dur) var(--ease), background var(--dur);
}
.nav-toggle span::before { position: absolute; top: -7px; }
.nav-toggle span::after { position: absolute; top: 7px; }
.is-open .nav-toggle span { background: transparent; }
.is-open .nav-toggle span::before { transform: translateY(7px) rotate(45deg); }
.is-open .nav-toggle span::after { transform: translateY(-7px) rotate(-45deg); }
@media (max-width: 820px) {
  :root { --header-h: 76px; }
  .nav-toggle { display: inline-flex; }
  .site-nav {
    position: fixed; inset: var(--header-h) 0 0 0; flex-direction: column; align-items: flex-start;
    gap: var(--sp-6); padding: var(--sp-8) var(--gutter); background: var(--c-navy);
    transform: translateX(100%); visibility: hidden;
    transition: transform var(--dur) var(--ease), visibility 0s linear var(--dur);
  }
  .site-nav a { font-size: var(--fs-h3); }
  .site-header.is-open .site-nav { transform: none; visibility: visible; transition: transform var(--dur) var(--ease); }
  .site-header.is-open { background: var(--c-navy); }
}

/* ---- 2. Hero ---------------------------------------------------------- */
.hero {
  --bg: var(--c-navy); --fg: var(--c-light); --fg-strong: var(--c-white); --fg-muted: var(--c-muted);
  --fg-inactive: rgba(var(--c-light-rgb), .28); --line: var(--c-muted); --line-soft: rgba(var(--c-light-rgb), .14); --accent: var(--c-accent);
  position: relative; isolation: isolate; display: flex; align-items: flex-end;
  /* One viewport plus the next panel's rounded overlap, so the first screen is
     hero only: the panel's curved top starts exactly at the fold. */
  min-height: calc(100vh + var(--panel-radius));
  min-height: calc(100svh + var(--panel-radius));
  padding-top: calc(var(--header-h) + var(--sp-9));
  padding-bottom: calc(var(--panel-radius) + clamp(4rem, 8vw, 9rem));
  background-color: var(--c-navy);
  background-position: center; background-size: cover; background-repeat: no-repeat;
  color: var(--c-light);
}
.hero::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--overlay-hero); }
.hero__inner { width: 100%; }
.hero__title { font-size: var(--fs-h1); font-weight: var(--fw-light); line-height: var(--lh-display); max-width: 30ch; }
.hero__sub { margin-top: var(--sp-8); max-width: 744px; font-size: var(--fs-body-lg); line-height: var(--lh-heading); }
.hero__cta { margin-top: var(--sp-8); display: flex; flex-wrap: wrap; gap: var(--sp-5) var(--sp-8); align-items: center; }
.hero__scroll { position: absolute; left: 50%; bottom: calc(var(--panel-radius) + var(--sp-6)); transform: translateX(-50%); }
.hero--compact { min-height: 640px; }
/* Short windows: tighter breathing room so the hero never outgrows one screen. */
@media (max-height: 900px) {
  .hero { padding-top: calc(var(--header-h) + var(--sp-6)); padding-bottom: calc(var(--panel-radius) + 2rem); }
}

/* ---- 3. Panels (sections with the brand's 60px rounded top) ------------ */
:root { --panel-radius: clamp(28px, 3.125vw, 60px); }
.panel {
  position: relative; border-radius: var(--panel-radius) var(--panel-radius) 0 0;
  margin-top: calc(var(--panel-radius) * -1);
}
.panel--image { background-position: center; background-size: cover; background-repeat: no-repeat; }

/* ---- 4. Links & buttons ---------------------------------------------- */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  font-size: var(--fs-nav); line-height: 1.6; padding: var(--sp-5) var(--sp-5) var(--sp-5) 0;
  color: var(--fg, inherit); transition: color var(--dur-fast);
}
.link-arrow svg { width: 18px; height: 18px; flex: none; transition: transform var(--dur) var(--ease); }
.link-arrow:hover { color: var(--accent, var(--c-accent)); }
.link-arrow:hover svg { transform: translate(3px, -3px); }
.link-arrow--down:hover svg { transform: translateY(4px); }
.link-arrow--sm { font-size: var(--fs-body); padding-block: var(--sp-3); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-3);
  min-height: 56px; padding: 0 var(--sp-7); border: 1px solid transparent; border-radius: var(--radius-0);
  font-size: var(--fs-nav); font-weight: var(--fw-medium); line-height: 1; white-space: nowrap;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast);
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 18px; height: 18px; }
.btn--primary { background: var(--c-accent); color: var(--c-white); border-color: var(--c-accent); }
.btn--primary:hover { background: var(--c-accent-hover); border-color: var(--c-accent-hover); }
.btn--outline { background: transparent; color: var(--fg); border-color: currentColor; }
.btn--outline:hover { background: var(--fg); color: var(--bg); }
.btn--sm { min-height: 44px; padding: 0 var(--sp-5); font-size: var(--fs-body); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .4; pointer-events: none; }

.btn-icon {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 50px; height: 50px; border-radius: var(--radius-arrow);
  background: var(--c-white); border: 1px solid var(--c-accent); color: var(--c-accent);
  transition: background var(--dur-fast), color var(--dur-fast), opacity var(--dur-fast), transform var(--dur-fast);
}
.btn-icon svg { width: 18px; height: 18px; }
.btn-icon:hover { background: var(--c-accent); color: var(--c-white); }
.btn-icon:disabled { opacity: .35; pointer-events: none; }
.btn-icon--ghost { background: transparent; border-color: var(--line); color: var(--fg); }
.btn-icon--ghost:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.btn-icon--round { border-radius: 50%; }

/* ---- 5. Chips, tags, dots -------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0 var(--sp-4);
  font-size: var(--fs-small); font-weight: var(--fw-medium); letter-spacing: var(--ls-caps); text-transform: uppercase;
  border: 1px solid var(--line-soft); color: var(--fg); background: transparent; border-radius: var(--radius-0);
  transition: border-color var(--dur-fast), background var(--dur-fast), color var(--dur-fast);
}
.chip:hover { border-color: var(--fg); }
.chip.is-active, .chip[aria-pressed="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); }
.tags {
  display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
  font-size: 11px; font-weight: var(--fw-medium); letter-spacing: .08em; text-transform: uppercase; line-height: 1.3;
}
.dots { display: flex; gap: var(--sp-2); justify-content: center; }
.dots button { --w: 0; width: calc(8px + 14px * var(--w)); height: 8px; padding: 0; border-radius: 4px; background: var(--fg-inactive); transition: background var(--dur-fast), width var(--dur) var(--ease); }
.dots button:hover { background: var(--fg-muted); }
.dots button[aria-current="true"] { --w: 1; background: var(--fg); }

/* ---- 6. Section furniture -------------------------------------------- */
.eyebrow { font-size: var(--fs-body); font-weight: var(--fw-medium); line-height: 1.2; color: var(--fg-strong); margin-bottom: var(--sp-10); }
.eyebrow--rule { display: flex; align-items: center; gap: var(--sp-4); }
.eyebrow--rule::after { content: ""; width: 40px; height: 1px; background: currentColor; }
.section-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-6); margin-bottom: var(--sp-9); }
.section-head .eyebrow { margin-bottom: 0; }

/* ---- 7. Statement (scroll-lit paragraph) ---------------------------- */
.statement { font-size: var(--fs-h1); font-weight: var(--fw-light); line-height: var(--lh-display); color: var(--fg); }
.statement__word { opacity: .12; transition: opacity .45s var(--ease); }
.statement__word.is-on { opacity: 1; }
.statement--static .statement__word { opacity: 1; }

/* ---- 8. Rotating word ----------------------------------------------- */
.headline { font-size: var(--fs-display-lg); font-weight: var(--fw-light); line-height: var(--lh-display); color: var(--fg); }
.rotator { display: inline-grid; vertical-align: top; text-align: left; }
.rotator__word {
  grid-area: 1 / 1; color: var(--accent); white-space: nowrap;
  opacity: 0; transform: translateY(.3em); filter: blur(6px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease), filter var(--dur-slow) var(--ease);
}
.rotator__word.is-active { opacity: 1; transform: none; filter: none; }
.rotator--plain .rotator__word { color: inherit; }
html:not(.js) .rotator__word:first-child { opacity: 1; transform: none; filter: none; }
@media (max-width: 640px) { .rotator__word { white-space: normal; } }

/* ---- 9. Kinetic statement (pinned, scroll-driven type scene) ----------
   Static by default: the lines simply stack. main.js adds .is-live (never
   under prefers-reduced-motion), which pins the block for --kinetic-run of
   scrolling while each line is built by its own effect:
   rise · track · spin · decode · ink · snap, then a finale.            */
.kinetic { position: relative; color: var(--accent); --kinetic-fs: min(var(--fs-display-lg), calc((100vw - 2 * var(--gutter)) / 8.9)); }
.kinetic__stack { display: flex; flex-direction: column; align-items: center; text-align: center; font-weight: var(--fw-light); }
.kinetic__line { display: block; position: relative; font-size: var(--kinetic-fs); line-height: 1.15; }
.kinetic__line--plus { font-size: var(--fs-display-xl); line-height: 1; }
.kinetic__inner { display: inline-block; position: relative; }
.k-word, .k-ch { display: inline-block; white-space: pre; }
.kinetic__pin > :not(.kinetic__stack) { display: none; }

/* live mode */
.kinetic.is-live { --kinetic-run: 350vh; height: calc(100vh + var(--kinetic-run)); }
@supports (height: 100svh) { .kinetic.is-live { height: calc(100svh + var(--kinetic-run)); } }
.kinetic.is-live .kinetic__pin { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.kinetic.is-live .kinetic__pin > * { display: block; }
/* soft fades so lines slide under the header and off the bottom instead of being cut */
.kinetic.is-live .kinetic__pin::before, .kinetic.is-live .kinetic__pin::after { content: ""; position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none; }
.kinetic.is-live .kinetic__pin::before { top: 0; height: calc(var(--header-h) + 90px); background: linear-gradient(var(--bg) 45%, transparent); }
.kinetic.is-live .kinetic__pin::after { bottom: 0; height: 90px; background: linear-gradient(transparent, var(--bg)); }
.kinetic__hint { z-index: 2; }
.kinetic.is-live .kinetic__stack { display: flex; position: absolute; left: 0; right: 0; top: calc(50% + var(--header-h) / 2); white-space: nowrap; will-change: transform; }
.kinetic.is-live .kinetic__line { visibility: hidden; will-change: transform, opacity; }
.kinetic.is-live .kinetic__line.is-shown { visibility: visible; }

.kinetic__glow {
  position: absolute; left: 50%; top: calc(50% + var(--header-h) / 2); width: min(110vw, 1500px); aspect-ratio: 1.7;
  background: radial-gradient(closest-side, rgba(var(--c-accent-rgb), .34), rgba(var(--c-accent-2-rgb), .12) 55%, transparent);
  translate: -50% -50%; opacity: 0; pointer-events: none; will-change: transform, opacity;
}
.kinetic__hint {
  position: absolute; left: 50%; bottom: var(--sp-8); transform: translateX(-50%);
  font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .2em; text-transform: uppercase; color: var(--fg-muted, var(--c-muted));
}
.kinetic__hint::after { content: ""; display: block; width: 1px; height: 36px; margin: var(--sp-3) auto 0; background: linear-gradient(var(--c-accent), transparent); transform-origin: top; animation: k-drip 1.8s var(--ease) infinite; }
@keyframes k-drip { 0% { transform: scaleY(0); opacity: 1; } 70% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }

/* line furniture created by main.js */
.k-sheen {
  color: transparent; -webkit-background-clip: text; background-clip: text; background-repeat: no-repeat;
  background-image: linear-gradient(90deg, var(--c-accent) 0 44%, #d2c2ff 49.5%, var(--c-accent-2) 52%, var(--c-accent) 58% 100%);
}
.k-ghost { position: absolute; left: 0; top: 0; pointer-events: none; }
.kinetic__line[data-fx="decode"] .k-ch { text-align: center; }
.k-ch.is-scr { color: var(--c-accent-2); }
.kinetic__caret {
  position: absolute; left: 0; top: .16em; height: .9em; width: max(2px, .05em); margin-left: .04em;
  background: var(--c-accent-2); box-shadow: 0 0 .25em var(--c-accent-2); opacity: 0;
}
.kinetic__caret.is-on { animation: k-blink .9s steps(1) infinite; }
@keyframes k-blink { 50% { visibility: hidden; } }
.k-outline { color: transparent; -webkit-text-stroke: max(1px, .011em) var(--c-accent); }
.k-fill { position: absolute; left: 0; top: 0; color: var(--c-accent); clip-path: inset(0 100% 0 0); }
.kinetic__pen { position: absolute; left: 0; top: .1em; height: 1.05em; width: 1px; background: var(--c-white); box-shadow: 0 0 10px rgba(var(--c-white-rgb), .9); opacity: 0; }
.kinetic__pen::before { content: ""; position: absolute; left: -4px; top: -4px; width: 9px; height: 9px; border-radius: 50%; background: var(--c-white); box-shadow: 0 0 14px 2px rgba(210, 194, 255, .9); }
.kinetic__sel { position: absolute; left: -.14em; right: -.14em; top: .1em; bottom: .02em; border: 1px solid var(--c-accent-2); opacity: 0; pointer-events: none; }
.kinetic__sel i { position: absolute; width: 9px; height: 9px; background: var(--c-white); border: 1px solid var(--c-accent-2); }
.kinetic__sel i:nth-child(1) { left: -5px; top: -5px; } .kinetic__sel i:nth-child(2) { right: -5px; top: -5px; }
.kinetic__sel i:nth-child(3) { left: -5px; bottom: -5px; } .kinetic__sel i:nth-child(4) { right: -5px; bottom: -5px; }
.kinetic__tag {
  position: absolute; left: 50%; top: calc(100% + 10px); transform: translateX(-50%); padding: 4px 7px; border-radius: 3px;
  background: var(--c-accent-2); color: var(--c-white); font-size: 11px; font-weight: var(--fw-medium); line-height: 1; letter-spacing: .04em; white-space: nowrap;
}
.kinetic__guide { position: absolute; left: -100vw; right: -100vw; height: 0; border-top: 1px dashed rgba(var(--c-accent-2-rgb), .55); opacity: 0; pointer-events: none; }
.kinetic__guide--top { top: .1em; } .kinetic__guide--bottom { bottom: .02em; }

@media (max-width: 767px) {
  .kinetic.is-live { --kinetic-run: 260vh; }
  .kinetic__hint { display: none !important; }
  .kinetic__tag { font-size: 11.5px; }
}

/* ---- 10. Carousel ---------------------------------------------------- */
.carousel { position: relative; --per-view: 3; --gap: var(--sp-7); }
.carousel__track {
  display: flex; gap: var(--gap); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; scroll-behavior: smooth;
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; }
.carousel__slide { flex: 0 0 calc((100% - (var(--per-view) - 1) * var(--gap)) / var(--per-view)); scroll-snap-align: start; min-width: 0; }
.carousel__dots { margin-top: var(--sp-8); }
.carousel__arrow { position: absolute; top: var(--arrow-top, 50%); transform: translateY(-50%); z-index: 2; }
.carousel__arrow--prev { left: calc((var(--gutter) - 6px) * -1); }
.carousel__arrow--next { right: calc((var(--gutter) - 6px) * -1); }
.carousel--peek { --per-view: 3.3; }
@media (prefers-reduced-motion: reduce) { .carousel__track { scroll-behavior: auto; } }
@media (max-width: 1024px) { .carousel { --per-view: 2; } .carousel--peek { --per-view: 2.2; } }
@media (max-width: 640px) {
  .carousel, .carousel--peek { --per-view: 1.15; --gap: var(--sp-4); }
  .carousel__arrow { display: none; }
}

/* ---- 11. Project card -------------------------------------------------- */
.project-card {
  position: relative; display: block; aspect-ratio: 577 / 672; overflow: hidden; isolation: isolate;
  background: var(--c-navy-2); color: var(--c-white);
}
.project-card__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.project-card:hover .project-card__img, .project-card:focus-visible .project-card__img { transform: scale(1.04); }
.project-card__top {
  position: absolute; inset: 0 0 auto 0; min-height: 80px; padding: var(--sp-5);
  display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-4);
  background: var(--overlay-top);
}
.project-card__top .tags { max-width: 80%; gap: 2px var(--sp-3); font-size: 12px; }
.project-card__arrow { flex: none; width: 40px; height: 40px; transition: transform var(--dur) var(--ease); }
.project-card:hover .project-card__arrow { transform: translate(3px, -3px); }
/* a shadow behind the title and text: dark at the bottom, fading out upward,
   so white text stays readable on light photos */
.project-card__body {
  position: absolute; inset: auto 0 0 0; padding: 110px var(--sp-5) var(--sp-5);
  background: linear-gradient(0deg, rgba(var(--c-black-rgb), .86) 0%, rgba(var(--c-black-rgb), .74) 36%, rgba(var(--c-black-rgb), .42) 68%, rgba(var(--c-black-rgb), .12) 88%, rgba(var(--c-black-rgb), 0) 100%);
}
.project-card__title { font-size: var(--fs-h3); line-height: 1.25; }
.project-card__desc { margin-top: var(--sp-3); font-size: var(--fs-small); line-height: 1.4; max-width: 62ch; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
@media (max-width: 1024px) { .project-card__arrow { width: 25px; height: 25px; } }

/* Selected work (main.js adds .is-live): the row can be grabbed with a mouse
   and thrown, a "View" / "Drag" disc replaces the cursor, the card under the
   pointer tilts under a soft light while the others dim, images slide inside
   their frames as the row moves (hence the slight zoom), and the cards rise
   in one after another the first time the row is seen (.is-armed → .is-in).
   The track gets vertical room so lifted cards and shadows are not cut. */
.carousel--work.is-live .carousel__track { padding-block: var(--sp-8); margin-block: calc(var(--sp-8) * -1); user-select: none; -webkit-user-select: none; }
.carousel--work.is-live .project-card, [data-cards].is-live .project-card { -webkit-user-drag: none; transition: opacity var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.carousel--work.is-live .project-card__img, [data-cards].is-live .project-card__img { transform: none; scale: 1.07; transition: scale .9s var(--ease); -webkit-user-drag: none; }
.carousel--work.is-live .project-card:hover .project-card__img, .carousel--work.is-live .project-card:focus-visible .project-card__img,
[data-cards].is-live .project-card:hover .project-card__img, [data-cards].is-live .project-card:focus-visible .project-card__img { transform: none; scale: 1.11; }
.carousel--work.is-live .project-card.is-hot, [data-cards].is-live .project-card.is-hot { box-shadow: 0 30px 60px -28px rgba(var(--c-black-rgb), .75); }
.carousel--work.is-hovering .project-card:not(.is-hot) { opacity: .6; }
/* On the light portfolio and project pages fading would turn the other cards
   milky, so they get a navy veil at 40% instead: the same as 60% opacity over
   the navy Selected Work section, so they darken exactly as on the home page. */
[data-cards] .project-card::after { content: ""; position: absolute; inset: 0; background: var(--c-navy); opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease); }
[data-cards].is-hovering .project-card:not(.is-hot)::after { opacity: .4; }
.project-card__glow {
  position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity var(--dur) var(--ease);
  background: radial-gradient(28rem circle at var(--gx, 50%) var(--gy, 50%), rgba(var(--c-white-rgb), .16), rgba(var(--c-white-rgb), 0) 62%);
}
.project-card.is-hot .project-card__glow { opacity: 1; }
/* what moves every frame gets its own layer, so the photos are not repainted:
   the Selected Work row always (eight cards), a grid card while it tilts */
.carousel--work.is-live .project-card, .project-card.is-moving, .work-disc { will-change: transform; }
.carousel--work.is-live .project-card__img, .project-card.is-moving .project-card__img { will-change: translate, scale; }
.carousel--work.is-live .carousel__track { cursor: grab; }
.carousel--work.is-dragging .carousel__track, .carousel--work.is-dragging .project-card { cursor: grabbing; }
.carousel--work.is-pointing .carousel__track, .carousel--work.is-pointing .project-card, [data-cards].is-pointing .project-card { cursor: none; }
/* smoked glass: a see-through dark disc that blurs the photo behind it, with
   a thin light rim; where blur is not supported it is a more solid navy */
.work-disc {
  position: absolute; left: 0; top: 0; z-index: 5; display: flex; align-items: center; justify-content: center; gap: 6px; width: 96px; height: 96px; margin: -48px 0 0 -48px; border-radius: 50%;
  border: 1px solid rgba(var(--c-white-rgb), .28); background: rgba(var(--c-navy-rgb), .32); color: var(--c-white);
  -webkit-backdrop-filter: blur(12px) saturate(1.4); backdrop-filter: blur(12px) saturate(1.4);
  font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .1em; text-transform: uppercase;
  pointer-events: none; opacity: 0; scale: .4; transition: opacity .25s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) { .work-disc { background: rgba(var(--c-navy-rgb), .78); } }
.work-disc svg { width: 14px; height: 14px; }
.carousel--work.is-pointing .work-disc, [data-cards].is-pointing .work-disc { opacity: 1; scale: 1; }
.carousel--work.is-dragging .work-disc { scale: .8; }
.carousel--work.is-armed .carousel__slide { clip-path: inset(100% 0 0 0); translate: 0 4rem; transition: clip-path 1.1s var(--ease) calc(var(--i, 0) * 90ms), translate 1.1s var(--ease) calc(var(--i, 0) * 90ms); }
.carousel--work.is-armed .project-card__img { scale: 1.25; transition: scale 1.4s var(--ease) calc(var(--i, 0) * 90ms); }
.carousel--work.is-armed .project-card__top, .carousel--work.is-armed .project-card__title, .carousel--work.is-armed .project-card__desc {
  opacity: 0; translate: 0 1.25rem; transition: opacity .7s var(--ease) calc(var(--i, 0) * 90ms + var(--d, .4s)), translate .7s var(--ease) calc(var(--i, 0) * 90ms + var(--d, .4s));
}
.carousel--work.is-armed .project-card__desc { --d: .5s; }
.carousel--work.is-armed .project-card__top { --d: .6s; }
.carousel--work.is-armed.is-in .carousel__slide { clip-path: inset(0); translate: none; }
.carousel--work.is-armed.is-in .project-card__img { scale: 1.07; }
.carousel--work.is-armed.is-in .project-card__top, .carousel--work.is-armed.is-in .project-card__title, .carousel--work.is-armed.is-in .project-card__desc { opacity: 1; translate: none; }
/* Card grids (portfolio, "See other projects"; main.js adds .is-live): the
   same mouse-over as Selected Work without the drag, and each card rises in
   when it first scrolls into view (.is-rising → .is-in). Only the .is-in
   state carries the transitions, so arming a visible card hides it at once. */
[data-cards].is-live { position: relative; }
[data-cards] .project-card.is-rising { clip-path: inset(100% 0 0 0); translate: 0 4rem; }
[data-cards] .project-card.is-rising .project-card__img { scale: 1.25; }
[data-cards] .project-card.is-rising .project-card__top, [data-cards] .project-card.is-rising .project-card__title, [data-cards] .project-card.is-rising .project-card__desc { opacity: 0; translate: 0 1.25rem; }
[data-cards] .project-card.is-rising.is-in { clip-path: inset(0); translate: none; transition: clip-path 1.1s var(--ease) calc(var(--i, 0) * 90ms), translate 1.1s var(--ease) calc(var(--i, 0) * 90ms); }
[data-cards] .project-card.is-rising.is-in .project-card__img { scale: 1.07; transition: scale 1.4s var(--ease) calc(var(--i, 0) * 90ms); }
[data-cards] .project-card.is-rising.is-in .project-card__top, [data-cards] .project-card.is-rising.is-in .project-card__title, [data-cards] .project-card.is-rising.is-in .project-card__desc {
  opacity: 1; translate: none; transition: opacity .7s var(--ease) calc(var(--i, 0) * 90ms + var(--d, .4s)), translate .7s var(--ease) calc(var(--i, 0) * 90ms + var(--d, .4s));
}
[data-cards] .project-card.is-rising .project-card__desc { --d: .5s; }
[data-cards] .project-card.is-rising .project-card__top { --d: .6s; }
@media (prefers-reduced-motion: reduce) {
  .carousel--work.is-live .project-card, .carousel--work.is-live .project-card__img, .project-card__glow { transition: none; }
  .carousel--work.is-live .project-card__img, .carousel--work.is-live .project-card:hover .project-card__img { scale: none; }
}

/* ---- 12. Capability card -----------------------------------------------
   The grid item (.cap-card) carries the scroll entrance and the column
   drift; the panel inside carries hover. On hover a white fill spreads from
   where the pointer came in (and shrinks back toward where it left), the
   panel lifts and tilts toward the pointer, the icon floats and the arrows
   light up one after another. Touch screens give the card crossing the
   middle of the screen the same state. Parts marked .cap-card__fx are added
   by main.js. */
.cap-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-7); }
.cap-card { perspective: 1200px; }
.cap-card__panel {
  position: relative; display: flex; flex-direction: column; height: 100%; padding: var(--sp-8); overflow: hidden; isolation: isolate;
  background: rgba(var(--c-white-rgb), .42); transition: box-shadow .6s var(--ease), opacity .5s var(--ease);
}
html:not(.js) .cap-card__panel:hover { background: var(--c-white); }
.cap-card__panel > :not(.cap-card__fx) { position: relative; z-index: 1; }
.cap-card__fx { position: absolute; z-index: 0; pointer-events: none; }
.cap-card__fill { left: 50%; top: 50%; width: 0; height: 0; border-radius: 50%; background: var(--c-white); transform: translate(-50%, -50%) scale(0); transition: transform .55s var(--ease); }
.cap-card__spot { inset: 0; opacity: 0; background: radial-gradient(460px circle at var(--mx, 50%) var(--my, 50%), rgba(var(--c-navy-rgb), .035), transparent 62%); transition: opacity .5s var(--ease); }
.cap-card__bar { left: 0; right: 0; bottom: 0; height: 2px; background: var(--c-accent); transform: scaleX(0); transform-origin: left; transition: transform .45s var(--ease); }
.cap-card.is-hot .cap-card__fill { transform: translate(-50%, -50%) scale(1); transition-duration: .8s; }
.cap-card.is-hot .cap-card__spot { opacity: 1; }
.cap-card.is-hot .cap-card__bar { transform: scaleX(1); transition: transform .9s var(--ease) .12s; }
.cap-card.is-hot .cap-card__panel { box-shadow: 0 40px 80px -36px rgba(var(--c-navy-rgb), .32); }
.cap-grid.has-hot .cap-card:not(.is-hot) .cap-card__panel { opacity: .55; }

.cap-card__icon-wrap { position: relative; display: inline-flex; align-items: flex-end; align-self: flex-start; height: 80px; }
.cap-card__icon { display: block; color: var(--c-navy); overflow: visible; transition: transform .7s cubic-bezier(.34, 1.56, .64, 1); }
.cap-card__icon-wrap::after {   /* soft shadow on the "floor" once the icon lifts */
  content: ""; position: absolute; left: 50%; bottom: -14px; width: 56px; height: 10px; border-radius: 50%;
  background: rgba(var(--c-navy-rgb), .22); filter: blur(6px); opacity: 0; transform: translateX(-50%) scale(.6); transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.cap-card.is-hot .cap-card__icon { transform: translateY(-10px) rotate(-8deg) scale(1.1); animation: cap-float 3.2s ease-in-out .7s infinite; }
.cap-card.is-hot .cap-card__icon-wrap::after { opacity: 1; transform: translateX(-50%) scale(1); }
@keyframes cap-float { 50% { translate: 0 -5px; } }

.cap-card__title { margin-top: var(--sp-6); font-size: var(--fs-h3); }
.cap-card__text { margin-top: var(--sp-5); max-width: 62ch; line-height: 1.45; color: #383838; }
.cap-card__text strong { font-weight: var(--fw-bold); color: var(--c-navy); }
.cap-card__text strong::before { content: "➤ "; transition: color .3s var(--ease); }
.cap-card.is-hot .cap-card__text strong::before { color: var(--c-accent); transition-delay: calc(var(--i, 0) * 45ms); }

/* entrance: cards rise in turn, each icon is drawn from the bottom up */
.js .cap-card.reveal { transform: none; translate: 0 64px; transition: opacity .9s var(--ease), translate 1.1s var(--ease); }
.js .cap-card.reveal:nth-child(even) { transition-delay: .12s; }
.js .cap-card.reveal.is-visible { translate: none; }
.js .cap-card.reveal .cap-card__icon-wrap { clip-path: inset(100% 0 0 0); scale: .7; transition: clip-path 1s var(--ease) .3s, scale 1s var(--ease) .3s; }
.js .cap-card.reveal.is-visible .cap-card__icon-wrap { clip-path: inset(-40% -40% -70% -40%); scale: none; }

/* faint light in the section that follows the pointer (added by main.js) */
.has-caps-light { position: relative; isolation: isolate; }
.caps-light { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.caps-light i {
  position: absolute; left: 0; top: 0; width: 1100px; height: 1100px; margin: -550px 0 0 -550px; border-radius: 50%; will-change: transform;
  background: radial-gradient(closest-side, rgba(var(--c-accent-rgb), .06), rgba(var(--c-accent-2-rgb), .035) 55%, transparent);
}

@media (max-width: 820px) { .cap-grid { grid-template-columns: 1fr; } .cap-card__panel { padding: var(--sp-7); } }
@media (prefers-reduced-motion: reduce) {
  .js .cap-card.reveal, .js .cap-card.reveal .cap-card__icon-wrap { translate: none; scale: none; clip-path: none; transition: none; }
  .cap-card__fill { transform: translate(-50%, -50%) scale(1); opacity: 0; transition: opacity .3s; }
  .cap-card.is-hot .cap-card__fill { opacity: 1; }
  .cap-card.is-hot .cap-card__icon { transform: none; animation: none; }
  .cap-card__bar { transform: none; opacity: 0; transition: opacity .3s; }
  .cap-card.is-hot .cap-card__bar { transform: none; opacity: 1; transition: opacity .3s; }
}

/* ---- 13. Experience rows ------------------------------------------------ */
.xp { border-top: var(--line-w) solid var(--line); }
.xp__row {
  display: grid; grid-template-columns: minmax(150px, 1fr) 170px minmax(0, 1.5fr) minmax(0, 1.5fr) 32px;
  gap: var(--sp-6); align-items: center; padding: var(--sp-7) 0; border-bottom: var(--line-w) solid var(--line);
}
.xp__period { font-size: var(--fs-small); font-weight: var(--fw-medium); color: var(--fg-strong); font-variant-numeric: tabular-nums; line-height: 1.3; }
.xp__type { display: block; margin-top: 2px; font-size: 12px; font-weight: var(--fw-regular); color: var(--fg); opacity: .8; }
.xp__logo { width: var(--brand-logo-w); height: var(--brand-logo-h); object-fit: contain; object-position: left; }
.xp__company { font-size: var(--fs-nav); font-weight: var(--fw-bold); line-height: 1.3; color: var(--fg-strong); }
.xp__loc { display: block; margin-top: var(--sp-1); font-size: 12px; font-weight: var(--fw-bold); line-height: 1.5; color: var(--fg); }
.xp__role { font-size: var(--fs-small); line-height: 1.45; color: var(--fg); }
.xp__link { justify-self: end; align-self: start; display: inline-flex; color: var(--fg); transition: color var(--dur-fast), transform var(--dur) var(--ease); }
.xp__link svg { width: 24px; height: 24px; }
.xp__row:hover .xp__link, .xp__link:focus-visible { color: var(--accent); transform: translate(3px, -3px); }
@media (max-width: 1024px) {
  .xp__row { grid-template-columns: 150px minmax(0, 1fr) 32px; grid-template-areas: "logo company link" "period role role"; row-gap: var(--sp-4); }
  .xp__row > :nth-child(1) { grid-area: period; } .xp__row > :nth-child(2) { grid-area: logo; }
  .xp__row > :nth-child(3) { grid-area: company; } .xp__row > :nth-child(4) { grid-area: role; } .xp__row > :nth-child(5) { grid-area: link; }
}
@media (max-width: 640px) {
  .xp__row { grid-template-columns: minmax(0, 1fr) 32px; grid-template-areas: "logo link" "company company" "role role" "period period"; row-gap: var(--sp-3); }
  .xp__logo { width: 120px; height: 36px; }
}

/* Live timeline (main.js wraps [data-xp] and adds .is-live; skipped under
   reduced motion). Rules draw left to right as rows enter, then each row
   rises. The row crossing the middle of the screen is lit and the rest
   recede; a rail on the left fills with the scroll, and the start year of the
   lit row rolls in large and outlined behind the list. With a mouse, the row
   under the pointer gets a soft light sheet, its arrow becomes a round button,
   and a preview card follows the pointer. */
.xp-wrap { position: relative; }
.xp.is-live { border-top-color: transparent; }
.xp.is-live::before { content: ""; display: block; height: 1px; margin-top: -1px; background: var(--line); transform-origin: left; transform: scaleX(0); transition: transform 1.2s var(--ease); }
.xp.is-live.is-in::before { transform: none; }
.xp.is-live .xp__row { position: relative; border-bottom-color: transparent; transition: opacity .5s var(--ease); }
.xp.is-live .xp__row::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--line); transform-origin: left; transform: scaleX(0); transition: transform 1.1s var(--ease) var(--d, 0s); }
.xp.is-live .xp__row::before {
  content: ""; position: absolute; inset: 0 calc(var(--sp-5) * -1); pointer-events: none; opacity: 0; transition: opacity .45s var(--ease);
  background: linear-gradient(90deg, rgba(var(--c-white-rgb), .075), rgba(var(--c-white-rgb), .02) 65%, transparent);
}
.xp.is-live .xp__row > * {
  position: relative; z-index: 1; opacity: 0; translate: 0 22px;
  transition: opacity .7s var(--ease) calc(var(--d, 0s) + .3s), translate .9s var(--ease) calc(var(--d, 0s) + .3s), transform .5s var(--ease);
}
.xp.is-live .xp__row.is-in::after { transform: none; }
.xp.is-live .xp__row.is-in > * { opacity: 1; translate: none; }
.xp.is-live .xp__role, .xp.is-live .xp__loc { transition: color .4s var(--ease); }

.xp.is-live.has-focus .xp__row:not(.is-active) { opacity: .3; }
.xp.is-live.has-hover .xp__row:not(.is-hover) { opacity: .45; }
.xp.is-live.has-hover .xp__row.is-hover { opacity: 1; }
.xp.is-live .xp__row.is-active > .xp__company, .xp.is-live .xp__row.is-hover > .xp__company { transform: translateX(14px); }
.xp.is-live .xp__row.is-hover::before { opacity: 1; }
.xp.is-live .xp__row.is-hover .xp__role, .xp.is-live .xp__row.is-hover .xp__loc { color: var(--fg-strong); }

.xp.is-live .xp__link { position: relative; display: grid; place-items: center; width: 44px; height: 44px; margin: -10px -10px 0 0; color: var(--fg); }
.xp.is-live .xp__link::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--c-white); transform: scale(0); transition: transform .45s cubic-bezier(.34, 1.56, .64, 1); }
.xp.is-live .xp__link svg { position: relative; width: 20px; height: 20px; transition: transform .45s var(--ease); }
.xp.is-live .xp__row:hover .xp__link { transform: none; color: var(--fg); }
.xp.is-live .xp__row.is-hover .xp__link, .xp.is-live .xp__link:focus-visible { color: var(--c-navy); }
.xp.is-live .xp__row.is-hover .xp__link::before, .xp.is-live .xp__link:focus-visible::before { transform: scale(1); }
.xp.is-live .xp__row.is-hover .xp__link svg, .xp.is-live .xp__link:focus-visible svg { transform: rotate(45deg); }

.xp-rail { position: absolute; top: 0; bottom: 0; left: calc(var(--gutter-lg) * -.5); width: 1px; background: rgba(var(--c-white-rgb), .12); pointer-events: none; }
.xp-rail i { position: absolute; inset: 0; background: linear-gradient(rgba(var(--c-white-rgb), .15), var(--c-white)); transform-origin: top; transform: scaleY(0); }
.xp-rail b {
  position: absolute; left: -4px; top: -4.5px; width: 9px; height: 9px; border-radius: 50%; background: var(--c-white); opacity: 0; transition: opacity .4s var(--ease);
  box-shadow: 0 0 0 5px rgba(var(--c-accent-rgb), .22), 0 0 22px 6px rgba(var(--c-accent-rgb), .45);
}
.xp-wrap.has-focus .xp-rail b { opacity: 1; }

.xp-year { position: absolute; top: 0; bottom: 0; right: 0; pointer-events: none; }
.xp-year__num {
  position: sticky; top: 50%; display: flex; translate: 0 -50%; opacity: 0; transition: opacity .6s var(--ease);
  font-size: clamp(8rem, 17vw, 16rem); font-weight: var(--fw-light); line-height: 1; letter-spacing: -.03em;
  color: transparent; -webkit-text-stroke: 1px rgba(var(--c-white-rgb), .16);
}
.xp-wrap.has-focus .xp-year__num { opacity: 1; }
.xp-year__col { display: block; height: 1em; overflow: hidden; }
.xp-year__col > span { display: block; transition: transform .9s cubic-bezier(.65, 0, .35, 1) var(--cd, 0s); }
.xp-year__col i { display: block; height: 1em; font-style: normal; }

.xp-peek {
  position: fixed; left: 0; top: 0; z-index: 30; width: 330px; padding: var(--sp-6) var(--sp-6) var(--sp-5); color: var(--c-white); pointer-events: none;
  background: rgba(16, 20, 32, .78); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid rgba(var(--c-white-rgb), .14); box-shadow: 0 40px 70px -24px rgba(var(--c-black-rgb), .7);
  opacity: 0; scale: .92; transition: opacity .3s var(--ease), scale .4s var(--ease); will-change: transform;
}
.xp-peek.is-on { opacity: 1; scale: 1; }
.xp-peek__body { transition: opacity .15s linear; }
.xp-peek.is-swap .xp-peek__body { opacity: 0; }
.xp-peek__logo { display: block; width: 190px; height: 58px; object-fit: contain; object-position: left; }
.xp-peek__dur { margin-top: var(--sp-5); font-size: 46px; font-weight: var(--fw-light); line-height: 1; }
.xp-peek__dur small { margin-left: 6px; font-size: 15px; opacity: .7; }
.xp-peek__meta { margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid rgba(var(--c-white-rgb), .14); font-size: 12.5px; line-height: 1.7; opacity: .8; }
@media (max-width: 640px) { .xp-year { display: none; } }

/* ---- 14. Stats ---------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); }
.stat { display: flex; flex-direction: column; }
.stat__num { order: -1; }
.stat__num { font-size: var(--fs-display-lg); font-weight: var(--fw-light); line-height: 1.1; color: var(--fg); font-variant-numeric: tabular-nums; }
.stat__label { margin-top: var(--sp-2); font-size: var(--fs-h4); font-weight: var(--fw-regular); line-height: var(--lh-body); color: var(--fg); }
@media (max-width: 640px) { .stats { grid-template-columns: 1fr; gap: var(--sp-7); } }
/* count-up (main.js, [data-count]): each digit rolls up like an odometer */
.odo { display: inline-flex; }
.odo__col { display: block; height: 1.1em; overflow: hidden; }
.odo__col > span { display: block; transition: transform 1.9s cubic-bezier(.16, 1, .3, 1) var(--cd, 0s); }
.odo__col i { display: block; height: 1.1em; font-style: normal; }
.odo__suffix { opacity: 0; transition: opacity .6s var(--ease) 1.2s; }
.is-run .odo__suffix { opacity: 1; }

/* ---- 15. Logo strips ---------------------------------------------------- */
.logo-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8) var(--sp-5); }
.logo-strip img { width: var(--brand-logo-w); height: var(--brand-logo-h); object-fit: contain; opacity: .9; transition: opacity var(--dur-fast); }
.logo-strip img:hover { opacity: 1; }
@media (max-width: 640px) { .logo-strip { display: grid; grid-template-columns: repeat(2, 1fr); justify-items: center; } .logo-strip img { width: 130px; } }
/* marquee (main.js, [data-marquee]): the strip is doubled and glides left,
   pausing under the pointer with the hovered logo lifted */
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, var(--c-black) 8%, var(--c-black) 92%, transparent); mask-image: linear-gradient(90deg, transparent, var(--c-black) 8%, var(--c-black) 92%, transparent); }
.logo-strip.is-marquee { display: flex; flex-wrap: nowrap; justify-content: flex-start; gap: 0; width: max-content; animation: marquee 42s linear infinite; }
.logo-strip.is-marquee li { flex: none; margin-right: var(--sp-10); }
.logo-strip.is-marquee img { transition: opacity .35s var(--ease), transform .45s var(--ease); }
.marquee:hover .logo-strip.is-marquee { animation-play-state: paused; }
.logo-strip.is-marquee:hover img { opacity: .4; }
.logo-strip.is-marquee li:hover img { opacity: 1; transform: translateY(-6px) scale(1.08); }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (max-width: 640px) { .logo-strip.is-marquee li { margin-right: var(--sp-8); } }

/* ---- 16. Reviews player ---------------------------------------------------
   One recommendation at a time in large type, with the people who wrote them
   listed beside it. main.js (.is-live) stacks the slides, reveals the words of
   the current one, sweeps a soft marker under its key phrases (data-hl), runs
   the auto-advance timer drawn as a line under the current name, and adds
   drag with a "Drag" cursor. Without JS the reviews simply follow each other. */
/* the head sits on the player's two columns: the eyebrow across, the intro
   over the quote, the count (styled like the tools total) over the names */
.reviews-head { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); gap: var(--sp-7) var(--sp-10); align-items: end; margin-bottom: var(--sp-10); }
.reviews-head .eyebrow { grid-column: 1 / -1; margin: 0; }
.reviews-head p:not(.rv-total) { grid-column: 1; max-width: 46ch; font-size: clamp(1.25rem, 1.55vw, 1.75rem); font-weight: var(--fw-light); line-height: 1.45; color: var(--fg-strong); }
.reviews-head .rv-total { grid-column: 2; margin: 0; }
.rv { position: relative; isolation: isolate; overflow-x: clip; }
.rv__stage { position: relative; display: flex; flex-direction: column; }
.rv__mark { width: 54px; height: 54px; color: var(--c-navy); transform-origin: 40% 60%; }
.rv__mark.is-pulse { animation: rv-mark .9s cubic-bezier(.34, 1.56, .64, 1); }
.rv__slides { display: grid; margin-top: var(--sp-7); }
.rv__slide { display: flex; flex-direction: column; gap: var(--sp-8); margin: 0; }
.rv__slide + .rv__slide { margin-top: var(--sp-10); }
.rv__quote { font-size: clamp(1.4rem, 2.25vw, 2.35rem); font-weight: var(--fw-light); line-height: 1.38; letter-spacing: -.005em; color: var(--c-navy); transition: transform .5s var(--ease), opacity .5s var(--ease); }
.rv__quote .w { display: inline-block; }
.rv__quote .m { background: linear-gradient(transparent 62%, rgba(var(--c-accent-rgb), .16) 62%) no-repeat; background-size: 0% 100%; }
.rv__by { display: flex; align-items: center; gap: var(--sp-5); margin-top: auto; }
.rv__by small { display: block; margin-top: 2px; font-size: var(--fs-small); line-height: 1.4; color: var(--fg-muted); }
.rv__name { display: block; font-size: var(--fs-nav); font-weight: var(--fw-bold); color: var(--c-navy); }
.rv__mono {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(var(--c-navy-rgb), .3);
  font-size: 14px; font-weight: var(--fw-bold); letter-spacing: .04em; color: var(--c-navy);
  transition: background .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease), box-shadow .4s var(--ease);
}
.rv__by .rv__mono { width: 52px; height: 52px; font-size: 16px; background: var(--c-navy); border-color: var(--c-navy); color: var(--c-white); }
.rv__ctrl, .rv__nav { display: none; }
.rv__ctrl { gap: var(--sp-3); }
.rv__ctrl .btn-icon { width: 48px; height: 48px; }
.rv__pause .rv__i-play, .rv.is-stopped .rv__pause .rv__i-pause { display: none; }
.rv.is-stopped .rv__pause .rv__i-play { display: block; }

.rv__nav { list-style: none; margin: 0; padding: 0; border-top: 1px solid rgba(var(--c-navy-rgb), .14); }
.rv__nav li { border-bottom: 1px solid rgba(var(--c-navy-rgb), .14); }
.rv__pick { position: relative; display: flex; align-items: center; gap: var(--sp-4); width: 100%; padding: var(--sp-5) 0; text-align: left; opacity: .5; transition: opacity .4s var(--ease); }
.rv__pick:hover, .rv__pick:focus-visible, .rv__pick[aria-current="true"] { opacity: 1; }
.rv__who { transition: translate .4s var(--ease); }
.rv__who b { display: block; font-size: 15px; font-weight: var(--fw-bold); color: var(--c-navy); }
.rv__who small { display: block; font-size: 12.5px; color: var(--fg-muted); }
.rv__num { margin-left: auto; font-size: 12px; font-weight: var(--fw-medium); color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.rv__pick:hover .rv__who { translate: 8px 0; }
.rv__pick[aria-current="true"] .rv__mono { background: var(--c-navy); border-color: var(--c-navy); color: var(--c-white); }
.rv__pick:not([aria-current="true"]):hover .rv__mono { background: var(--c-white); border-color: var(--c-white); box-shadow: 0 8px 20px -8px rgba(var(--c-navy-rgb), .35); }
.rv__prog { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--c-accent); transform-origin: left; transform: scaleX(0); }
.rv__pick[aria-current="true"] .rv__prog { animation: rv-prog var(--rv-dur, 8s) linear forwards; }
.rv.is-paused .rv__pick[aria-current="true"] .rv__prog { animation-play-state: paused; }
.rv.is-stopped .rv__pick[aria-current="true"] .rv__prog { animation: none; transform: scaleX(1); opacity: .45; }

.rv__bgmark { position: absolute; z-index: -1; right: 0; bottom: -60px; width: 460px; height: 460px; color: transparent; stroke: rgba(var(--c-navy-rgb), .09); stroke-width: .12; pointer-events: none; transition: transform 1.4s var(--ease); }
.rv__drag {
  position: absolute; left: 0; top: 0; z-index: 5; display: grid; place-items: center; width: 96px; height: 96px; margin: -48px 0 0 -48px; border-radius: 50%;
  background: var(--c-navy); color: var(--c-white); font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .1em; text-transform: uppercase;
  pointer-events: none; opacity: 0; scale: .4; transition: opacity .25s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
.rv__stage.is-pointing .rv__drag { opacity: 1; scale: 1; }
.rv__stage.is-dragging .rv__drag { scale: .8; }

.rv.is-live { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); gap: var(--sp-8) var(--sp-10); align-items: start; }
.rv.is-live .rv__stage { grid-column: 1; grid-row: 1 / span 2; }
.rv.is-live .rv__side { grid-column: 2; grid-row: 1; min-width: 0; }
.rv.is-live .rv-cta { grid-column: 2; grid-row: 2; justify-self: start; }   /* starts in line with the avatars */
.rv.is-live .rv__ctrl { display: flex; position: absolute; right: 0; bottom: 2px; }
.rv.is-live .rv__nav { display: block; }
.rv.is-live .rv__slides { grid-template-areas: "slide"; touch-action: pan-y; }
.rv.is-live .rv__stage.is-pointing .rv__slides { cursor: none; }
.rv.is-live .rv__slide { grid-area: slide; margin: 0; visibility: hidden; opacity: 0; transition: opacity .35s var(--ease), visibility 0s .35s; }
.rv.is-live .rv__slide.is-current { visibility: visible; opacity: 1; transition: opacity .35s var(--ease); }
.rv.is-live .rv__by { padding-right: 190px; }
.rv.is-live .rv__slide.is-current .w { animation: rv-word .8s var(--ease) both; animation-delay: calc(var(--i, 0) * 18ms); }
.rv.is-live .rv__slide.is-current .m { background-size: 100% 100%; transition: background-size .35s var(--ease) calc(var(--n, 20) * 18ms + .5s + var(--h, 0) * .5s + var(--k, 0) * 60ms); }
.rv__stage.is-dragging .rv__quote { transition: none; }

/* long texts (main.js adds .is-clamped past --rv-lines + 1 lines): the rest opens in place */
.rv { --rv-lines: 5; }
.rv__slide.is-clamped:not(.is-open) .rv__quote p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--rv-lines); overflow: hidden; }
.rv__more { display: none; }
.rv__slide.is-clamped .rv__more {
  display: inline-flex; align-self: flex-start; align-items: center; gap: 10px; margin-top: calc(var(--sp-5) * -1); padding: 6px 0;
  border-bottom: 1px solid currentColor; font-size: var(--fs-nav); font-weight: var(--fw-medium); color: var(--c-navy);
}

/* many recommendations (main.js adds .has-many past five): the names become a
   five-row scrolling window with a counter and a thin position track that
   follows the current one; on phones the avatar row scrolls sideways */
.rv__side { position: relative; }
.rv__list { position: relative; }
.rv__count, .rv__track { display: none; }
.rv.has-many .rv__count { display: flex; align-items: baseline; gap: 6px; margin: 0 0 var(--sp-4); font-size: 13px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.rv__count b { font-size: 26px; font-weight: var(--fw-light); color: var(--c-navy); }
.rv__count span { margin-left: auto; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
.rv.has-many .rv__side { padding-right: 14px; }
.rv.has-many .rv__nav {
  --ft: 12%; --fb: 12%; position: relative; max-height: var(--rv-window, 425px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(transparent, var(--c-black) var(--ft), var(--c-black) calc(100% - var(--fb)), transparent); mask-image: linear-gradient(transparent, var(--c-black) var(--ft), var(--c-black) calc(100% - var(--fb)), transparent);
}
.rv.has-many .rv__nav::-webkit-scrollbar { display: none; }
.rv.has-many .rv__nav.at-start { --ft: 0%; }
.rv.has-many .rv__nav.at-end { --fb: 0%; }
.rv.has-many .rv__track { display: block; position: absolute; top: 0; bottom: 0; right: -12px; width: 2px; background: rgba(var(--c-navy-rgb), .1); }
.rv__track i { position: absolute; left: 0; top: 0; width: 100%; border-radius: 2px; background: var(--c-navy); }
@keyframes rv-word { from { opacity: 0; filter: blur(8px); transform: translateY(.45em); } }
@keyframes rv-mark { 40% { transform: rotate(-24deg) scale(1.18); } }
@keyframes rv-prog { to { transform: scaleX(1); } }

/* write-a-review button: fills navy, its arrow turns; main.js adds a slight magnetic pull */
.rv-cta {
  display: inline-flex; align-items: center; gap: var(--sp-4); padding: 18px 28px; border: 1px solid var(--c-navy); border-radius: var(--radius-pill);
  font-size: var(--fs-nav); line-height: 1.2; color: var(--c-navy); background: var(--bg); transition: background .35s var(--ease), color .35s var(--ease);
}
.rv-cta svg { width: 20px; height: 20px; transition: transform .45s var(--ease); }
.rv-cta:hover, .rv-cta:focus-visible { background: var(--c-navy); color: var(--c-white); }
.rv-cta:hover svg, .rv-cta:focus-visible svg { transform: rotate(45deg); }
@media (max-width: 480px) { .rv-cta { gap: var(--sp-3); padding: 15px 20px; font-size: 15px; white-space: nowrap; } }

@media (max-width: 820px) {
  .reviews-head { grid-template-columns: 1fr; gap: var(--sp-5); margin-bottom: var(--sp-9); }
  .reviews-head .rv-total { grid-column: 1; }
  .rv.is-live { grid-template-columns: 1fr; gap: var(--sp-6); }
  .rv.is-live .rv__stage, .rv.is-live .rv__side, .rv.is-live .rv-cta { grid-column: auto; grid-row: auto; }
  .rv.is-live .rv__side { order: -1; }
  .rv.is-live .rv__nav { display: flex; gap: var(--sp-3); padding-bottom: var(--sp-3); border: 0; }
  .rv__nav li { border: 0; }
  .rv__pick { width: auto; padding: 0; }
  .rv__who, .rv__num { display: none; }
  .rv__prog { bottom: -10px; }
  .rv__mark { width: 40px; height: 40px; }
  .rv__quote { font-size: 1.3rem; }
  .rv { --rv-lines: 8; }
  .rv.has-many .rv__side { padding-right: 0; }
  .rv.has-many .rv__nav {
    max-height: none; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity;
    -webkit-mask-image: linear-gradient(90deg, transparent, var(--c-black) var(--ft), var(--c-black) calc(100% - var(--fb)), transparent); mask-image: linear-gradient(90deg, transparent, var(--c-black) var(--ft), var(--c-black) calc(100% - var(--fb)), transparent);
  }
  .rv.has-many .rv__nav li { scroll-snap-align: center; }
  .rv.has-many .rv__track { display: none; }
  .rv.is-live .rv__by { padding-right: 0; }
  .rv.is-live .rv__ctrl { position: static; margin-top: var(--sp-6); }
  .rv__bgmark { width: 280px; height: 280px; bottom: -20px; }
}
@media (prefers-reduced-motion: reduce) {
  .rv.is-live .rv__slide, .rv.is-live .rv__slide.is-current { transition: none; }
  .rv.is-live .rv__slide.is-current .w { animation: none; }
  .rv.is-live .rv__slide.is-current .m { transition: none; }
}

/* ---- 17. Tools & certificates ------------------------------------------- */
.tools { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--sp-7) var(--sp-5); }
.tool { display: flex; align-items: center; justify-content: center; height: var(--tool-logo-h); }
.tool img { max-width: min(100%, var(--tool-logo-w)); max-height: var(--tool-logo-h); width: auto; height: auto; object-fit: contain; }
@media (max-width: 1024px) { .tools { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 640px) { .tools { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); } .tool { height: 56px; } }

/* Live tools (main.js on [data-tools], skipped under reduced motion for the
   motion parts). Logos sit straight on the panel in one light tone; near the
   pointer they brighten and grow with closeness, a faint light follows it, and
   the one under it takes back its colours with its name and area below. Area
   buttons filter the grid: the rest fade out and the kept ones glide into
   place. On first view the logos ripple in from the middle. */
.tools-head, .creds-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-6); flex-wrap: wrap; margin-bottom: var(--sp-8); }
.tools-head .eyebrow, .creds-head .eyebrow { margin: 0 0 var(--sp-3); }
.tools-total, .creds-total, .rv-total { font-size: clamp(2.6rem, 4vw, 4rem); font-weight: var(--fw-light); line-height: 1; color: var(--fg-strong); font-variant-numeric: tabular-nums; }
.tools-total small, .creds-total small, .rv-total small { margin-left: 10px; font-size: 15px; letter-spacing: .02em; color: var(--fg-muted, rgba(var(--c-white-rgb), .55)); }
.tools-filter, .creds-switch { position: relative; display: flex; gap: 6px; padding: 5px; border: 1px solid rgba(var(--c-white-rgb), .12); border-radius: var(--radius-pill); }
.tools-filter__pill, .creds-switch__pill { position: absolute; top: 5px; bottom: 5px; left: 0; width: 0; border-radius: var(--radius-pill); background: var(--c-white); transition: transform .45s var(--ease), width .45s var(--ease); }
.tools-chip, .creds-switch__btn { position: relative; display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: var(--radius-pill); font-size: 14px; white-space: nowrap; color: rgba(var(--c-white-rgb), .72); transition: color .3s var(--ease); }
.tools-chip small, .creds-switch__btn small { font-size: 11px; opacity: .55; font-variant-numeric: tabular-nums; }
.tools-chip:hover, .creds-switch__btn:hover { color: var(--c-white); }
.tools-chip[aria-pressed="true"], .creds-switch__btn[aria-pressed="true"] { color: var(--c-navy); }
.tools-chip:focus-visible, .creds-switch__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tools.is-live { position: relative; gap: 0; }
.tools.is-live::before {
  content: ""; position: absolute; left: 0; top: 0; width: 560px; height: 560px; margin: -280px 0 0 -280px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(var(--c-white-rgb), .07), rgba(var(--c-accent-rgb), .05) 55%, transparent);
  transform: translate(var(--mx, 0), var(--my, 0)); opacity: var(--glow, 0); transition: opacity .4s var(--ease);
}
.tools.is-live .tool { position: relative; flex-direction: column; height: 132px; }
.tools.is-live .tool img {
  max-width: min(74%, var(--tool-logo-w)); max-height: 64px; filter: grayscale(1) brightness(2.1); opacity: var(--o, .6); scale: var(--s, 1);
  transition: filter .35s var(--ease), opacity .3s var(--ease), scale .4s var(--ease);
}
.tools.is-live .tool.is-hot img { filter: none; opacity: 1; scale: 1.14; }
.tools.is-live .tool.is-out { display: none; }
.tool__name {
  position: absolute; left: 0; right: 0; bottom: 6px; text-align: center; font-size: 12.5px; font-weight: var(--fw-medium); color: var(--fg-strong);
  opacity: 0; translate: 0 6px; transition: opacity .3s var(--ease), translate .3s var(--ease); pointer-events: none;
}
.tool__name small { margin-left: 6px; font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: rgba(var(--c-white-rgb), .45); }
.tool.is-hot .tool__name { opacity: 1; translate: none; }
.tools.is-live:not(.is-in) .tool { opacity: 0; }
.tools.is-live .tool.tools-ghost { position: absolute; margin: 0; pointer-events: none; }
@media (max-width: 820px) {
  .tools-head { display: block; }
  .tools-total { margin-bottom: var(--sp-5); }
  .tools-filter { overflow-x: auto; scrollbar-width: none; border: 0; padding: 0; gap: 8px; margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); }
  .tools-filter::-webkit-scrollbar { display: none; }
  .tools-filter__pill { display: none; }
  .tools-chip { border: 1px solid rgba(var(--c-white-rgb), .18); }
  .tools-chip[aria-pressed="true"] { background: var(--c-white); border-color: var(--c-white); }
}
@media (prefers-reduced-motion: reduce) { .tools.is-live::before { display: none; } .tools.is-live .tool.is-hot img { scale: none; } .tools-filter__pill { transition: none; } }
@media (max-width: 640px) { .tools.is-live .tool { height: 100px; } .tools.is-live .tool img { max-height: 48px; max-width: 86%; } .tool__name { font-size: 11px; bottom: 2px; } .tool__name small { display: none; } }
/* Credentials stage: [data-creds] turns the certificate and letter carousels
   into one stage (main.js). The current item sits large in the middle and its
   neighbours get smaller, dimmer and turned towards it on a looping rail; a
   switch changes group, the title and number sit below, and a ruler with one
   line per item jumps anywhere. With a mouse the current item tilts with a
   light sheen and a "View" / "Drag" disc replaces the cursor. */
.creds-head { margin-bottom: var(--sp-6); }
.creds-switch__short { display: none; }
.creds-stage { position: relative; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.creds-stage:focus-visible { outline: none; }
.creds-rail {
  --rail-pad: 90px; position: relative; height: calc(var(--cw, 480px) / var(--ar, 1.3) + var(--rail-pad)); margin: 0; padding: 0; list-style: none; perspective: 1600px; overflow-x: clip;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--c-black) 9%, var(--c-black) 91%, transparent); mask-image: linear-gradient(90deg, transparent, var(--c-black) 9%, var(--c-black) 91%, transparent);
}
.creds-card { position: absolute; left: 50%; top: 50%; width: var(--cw, 480px); margin-left: calc(var(--cw, 480px) / -2); will-change: transform, opacity; }
.creds-card.is-away { display: none; }
.creds .cert { position: relative; cursor: pointer; }
.creds-card.is-now .cert { cursor: zoom-in; }
.creds .cert img {
  border-radius: 3px; background: var(--c-white);
  box-shadow: 0 40px 70px -30px rgba(var(--c-black-rgb), .85), 0 0 0 1px rgba(var(--c-white-rgb), .06); transition: box-shadow .6s var(--ease);
}
.creds .cert:hover img { transform: none; }
.creds-card.is-now img { box-shadow: 0 50px 90px -30px rgba(var(--c-black-rgb), .9), 0 0 0 1px rgba(var(--c-white-rgb), .1), 0 0 120px -20px rgba(var(--c-accent-rgb), .35); }
.creds .cert:focus-visible { outline: none; }
.creds .cert:focus-visible img { outline: 2px solid var(--accent); outline-offset: 6px; }
.creds .cert__cap { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.creds-sheen {
  position: absolute; inset: 0; border-radius: 3px; pointer-events: none; opacity: var(--shine, 0); mix-blend-mode: multiply;
  background: linear-gradient(115deg, transparent 28%, rgba(205, 180, 255, .55) 42%, rgba(160, 190, 255, .5) 50%, rgba(255, 214, 240, .45) 57%, transparent 70%) var(--sx, 50%) 0 / 240% 100% no-repeat;
}
.creds-disc {
  position: absolute; left: 0; top: 0; z-index: 120; display: grid; place-items: center; width: 96px; height: 96px; margin: -48px 0 0 -48px; border-radius: 50%;
  background: var(--c-white); color: var(--c-navy); font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .1em; text-transform: uppercase;
  pointer-events: none; opacity: 0; scale: .4; transition: opacity .25s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
.creds-stage.is-pointing, .creds-stage.is-pointing .cert { cursor: none; }
.creds-stage.is-pointing .creds-disc { opacity: 1; scale: 1; }
.creds-stage.is-dragging .creds-disc { scale: .8; }

.creds-cap { margin: var(--sp-2) 0 0; text-align: center; }
.creds-cap__n { display: block; margin-bottom: 10px; font-size: 13px; letter-spacing: .14em; color: rgba(var(--c-white-rgb), .5); font-variant-numeric: tabular-nums; }
.creds-cap__n b { font-weight: var(--fw-medium); color: var(--c-white); }
.creds-cap__ts { display: grid; min-height: 2.5em; font-size: var(--fs-h3); line-height: 1.25; }
.creds-cap__t { grid-area: 1 / 1; max-width: 36ch; margin-inline: auto; font-weight: var(--fw-light); color: var(--c-white); animation: creds-in .55s var(--ease) both; }
.creds-cap__t.is-out { animation: creds-out .35s var(--ease) both; }
@keyframes creds-in { from { opacity: 0; translate: 0 calc(var(--dir, 1) * 14px); filter: blur(3px); } }
@keyframes creds-out { to { opacity: 0; translate: 0 calc(var(--dir, 1) * -14px); filter: blur(3px); } }
.creds-hint { display: none; }

.creds-foot { display: flex; align-items: center; gap: var(--sp-7); margin-top: var(--sp-6); }
.creds-scrub { position: relative; flex: 1; display: flex; align-items: flex-end; justify-content: space-between; height: 34px; cursor: pointer; touch-action: none; }
.creds-scrub:focus-visible { outline: 2px solid var(--accent); outline-offset: 8px; border-radius: 2px; }
.creds-scrub i {
  display: block; width: 2px; height: 9px; border-radius: 2px; background: rgba(var(--c-white-rgb), .22); transform-origin: bottom; pointer-events: none;
  transition: height .25s var(--ease), background-color .25s var(--ease), scale .5s var(--ease) calc(var(--i, 0) * 12ms);
}
.creds-scrub i.is-on { background: var(--c-accent); }
.creds.is-live:not(.is-in) .creds-scrub i { scale: 1 0; }
.creds-tip {
  position: absolute; bottom: 44px; left: 0; z-index: 2; padding: 9px 14px; border-radius: 8px; background: var(--c-white); color: var(--c-navy);
  font-size: 13px; white-space: nowrap; box-shadow: 0 14px 30px -12px rgba(var(--c-black-rgb), .6); translate: -50% 4px; opacity: 0; pointer-events: none;
  transition: opacity .2s var(--ease), translate .2s var(--ease);
}
.creds-tip.is-on { opacity: 1; translate: -50% 0; }
.creds-tip small { margin-right: 8px; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.creds-tip::after { content: ""; position: absolute; left: calc(50% + var(--ax, 0px)); bottom: -5px; width: 10px; height: 10px; margin-left: -5px; background: inherit; rotate: 45deg; }
.creds-arrows { display: flex; gap: 10px; }
.creds-arrows .btn-icon:disabled { opacity: .3; pointer-events: none; }
@media (max-width: 820px) {
  .creds-head { display: block; }
  .creds-total { margin-bottom: var(--sp-5); }
  .creds-switch { display: grid; grid-template-columns: 1fr 1fr; }
  .creds-switch__btn { justify-content: center; padding: 10px 8px; font-size: 13px; }
  .creds-switch__long { display: none; }
  .creds-switch__short { display: inline; }
  .creds-rail { --rail-pad: 40px; margin-inline: calc(var(--gutter) * -1); -webkit-mask-image: none; mask-image: none; }
  .creds-cap__ts { font-size: 19px; }
  .creds-scrub { height: 26px; }
}
@media (max-width: 640px) { .creds-arrows { display: none; } .creds-foot { margin-top: var(--sp-4); } }
@media (hover: none) { .creds-hint { display: block; margin-top: 6px; text-align: center; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: rgba(var(--c-white-rgb), .4); } }
@media (prefers-reduced-motion: reduce) {
  .creds-cap__t, .creds-cap__t.is-out { animation: none; }
  .creds-cap__t.is-out { display: none; }
  .creds-scrub i, .creds-switch__pill, .creds .cert img { transition: none; }
  .creds-disc { display: none; }
}
.carousel--certs { --per-view: 5; --gap: var(--sp-7); --arrow-top: 40%; }
@media (max-width: 1024px) { .carousel--certs { --per-view: 3; } }
@media (max-width: 640px) { .carousel--certs { --per-view: 1.6; --gap: var(--sp-4); } }
.cert { display: block; width: 100%; text-align: center; cursor: zoom-in; color: inherit; }
.cert img { width: 100%; aspect-ratio: 348 / 269; object-fit: cover; object-position: top; background: var(--bg-raised); transition: transform var(--dur) var(--ease), opacity var(--dur); }
.cert:hover img { transform: translateY(-4px); }
.cert--letter img { aspect-ratio: 348 / 246; }
.cert__cap { display: block; margin-top: var(--sp-4); font-size: var(--fs-small); line-height: 1.4; color: var(--fg-muted); }
.scroller { position: relative; }
.scroller__nav { display: flex; gap: var(--sp-3); }
.scroller__track { display: flex; gap: var(--sp-7); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.scroller__track::-webkit-scrollbar { display: none; }
.scroller__track > * { flex: none; scroll-snap-align: start; }

/* ---- 18. Contact banner --------------------------------------------------- */
.banner {
  --bg: var(--c-navy); --fg: var(--c-navy); --fg-muted: var(--c-muted); --accent: var(--c-accent);
  position: relative; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center;
  min-height: clamp(36rem, 62vw, 74.6rem); padding: var(--section-y) var(--gutter) calc(var(--section-y) + var(--panel-radius));
  background-color: var(--c-navy); background-position: center; background-size: max(100%, 58rem) auto; background-repeat: no-repeat;
  color: var(--c-navy);
}
.banner__title { font-size: clamp(3rem, 9vw, 10.8rem); font-weight: var(--fw-light); line-height: 1; }
.banner__meta { margin-top: var(--sp-8); color: var(--c-accent); }
.banner__share-label { margin-top: var(--sp-4); font-size: 11px; color: var(--c-slate); }
.social { display: flex; justify-content: center; gap: var(--sp-5); margin-top: var(--sp-8); }
.social a { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; color: var(--c-navy); transition: color var(--dur-fast), transform var(--dur-fast); }
.social a:hover { color: var(--c-accent); transform: translateY(-2px); }
.social svg { width: 16px; height: 16px; }
.banner--compact { min-height: 520px; }

/* Dots that write the title ([data-halftone], main.js): a canvas draws the
   halftone as light dots on navy and moves them into the title's letters as
   the banner scrolls in; the real title stays for screen readers and layout
   but is see-through. --made (0 to 1) fades the rest in at the end, and the
   finished banner is navy, so text and buttons turn light. */
.banner__fx { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.banner.is-live { --made: 1; background-image: none !important; }
.banner.is-live > :not(.banner__fx) { position: relative; z-index: 1; }
.banner.is-live .banner__title { color: transparent; }
.banner.is-live .banner__meta { color: #b08bff; }
.banner.is-live .banner__meta, .banner.is-live .social, .banner.is-live .banner__share-label { opacity: clamp(0, calc((var(--made) - .8) * 5), 1); }
.banner.is-live .social:focus-within, .banner.is-live .social:focus-within ~ .banner__share-label, .banner.is-live:has(.social:focus-within) .banner__share-label { opacity: 1; }
.banner.is-live .banner__share-label, .banner.is-live .banner__share { color: rgba(var(--c-light-rgb), .6); }
.banner__count { font-variant-numeric: tabular-nums; }

/* share buttons on the banner: outline circles that fill on hover; the label
   under them names the one under the pointer */
.banner .social { gap: 14px; }
.banner .social a, .social__copy {
  display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; padding: 0; border: 1px solid rgba(var(--c-navy-rgb), .25); border-radius: 50%;
  background: rgba(var(--c-light-rgb), .6); color: var(--c-navy); cursor: pointer;
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
.banner .social a:hover, .banner .social a:focus-visible, .social__copy:hover, .social__copy:focus-visible { background: var(--c-navy); border-color: var(--c-navy); color: var(--c-white); scale: 1.08; transform: none; }
.banner .social a:focus-visible, .social__copy:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 3px; }
.social__copy svg { width: 17px; height: 17px; }
.social__copy.is-done, .social__copy.is-done:hover { background: var(--c-accent); border-color: var(--c-accent); color: var(--c-white); }
.banner__share-label { min-height: 1.4em; transition: color .3s var(--ease); }
.banner__share-label.is-done { color: var(--c-accent); }
.banner.is-live .banner__share-label.is-done { color: #b08bff; }
.banner.is-live .social a, .banner.is-live .social__copy { border-color: rgba(var(--c-light-rgb), .3); background: transparent; color: var(--c-light); }
.banner.is-live .social a:hover, .banner.is-live .social a:focus-visible, .banner.is-live .social__copy:hover, .banner.is-live .social__copy:focus-visible { background: var(--c-light); border-color: var(--c-light); color: var(--c-navy); }
.banner.is-live .social__copy.is-done, .banner.is-live .social__copy.is-done:hover { background: var(--c-accent); border-color: var(--c-accent); color: var(--c-white); }
@media (max-width: 640px) { .banner .social { gap: 9px; } .banner .social a, .social__copy { width: 44px; height: 44px; } }
@media (prefers-reduced-motion: reduce) { .banner .social a, .social__copy { transition: none; } .banner .social a:hover, .social__copy:hover { scale: none; } }

/* ---- 19. Footer ------------------------------------------------------------- */
/* A white panel: the title with a hint, the contact list opposite it, then
   room below where pills fall into a pile and can be thrown around (main.js
   "Footer playground"; the stage covers the title too, so pills fall past
   it). The purple pills are contact links as well. Without JS the pills sit
   as wrapped rows; .is-live reserves the pile's room under the head and lets
   main.js place every pill with translate and rotate. */
.site-footer { --pill-fs: clamp(.875rem, 1.36vw, 1.5rem); overflow: hidden; overflow: clip; }
.site-footer__stage { position: relative; }
.site-footer__head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "intro contact" "hint contact"; align-items: start;
  gap: var(--sp-6) var(--sp-8); padding-top: clamp(2.5rem, 4.4vw, 5rem);
}
.site-footer__head > div:first-child { grid-area: intro; }
.site-footer__title { font-size: clamp(3rem, 9vw, 10.8rem); font-weight: var(--fw-light); line-height: .95; letter-spacing: -.035em; color: var(--fg-strong); }
.site-footer__role { margin-top: var(--sp-5); font-size: var(--fs-nav); color: var(--fg-muted); }
.site-footer__hint { grid-area: hint; font-size: var(--fs-small); line-height: 1.6; color: var(--fg-muted); }
.site-footer__hint span { color: var(--accent); }
.playground { display: grid; gap: var(--sp-3); padding: var(--sp-9) var(--gutter) var(--sp-10); }
.playground__list { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
/* contact list opposite the title: the address large with a round go
   button over a bold rule, then one row per channel */
.footer-contact { grid-area: contact; width: min(30rem, 36vw); padding-top: clamp(.5rem, 1.4vw, 1.75rem); }
.footer-contact__mail {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-5); padding-bottom: var(--sp-5);
  border-bottom: 2px solid var(--fg); font-size: clamp(1.25rem, 1.7vw, 2rem); letter-spacing: -.01em; overflow-wrap: anywhere;
}
.footer-contact__go {
  flex: none; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--c-navy); color: var(--c-white);
  transition: background-color .3s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
.footer-contact__go svg { width: 18px; height: 18px; transition: rotate .35s var(--ease); }
.footer-contact__mail:hover .footer-contact__go, .footer-contact__mail:focus-visible .footer-contact__go { background: var(--accent); scale: 1.06; }
.footer-contact__mail:hover .footer-contact__go svg, .footer-contact__mail:focus-visible .footer-contact__go svg { rotate: 45deg; }
.footer-contact__list li + li { border-top: 1px solid var(--line-soft); }
.footer-contact__list a { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) 0; }
.footer-contact__list b { font-weight: var(--fw-medium); transition: color var(--dur-fast); }
.footer-contact__list span { font-size: 12px; letter-spacing: .02em; color: var(--fg-muted); }
.footer-contact__list svg { width: 16px; height: 16px; margin-left: auto; flex: none; color: var(--fg-muted); transition: color var(--dur-fast), translate var(--dur-fast) var(--ease); }
.footer-contact__list a:hover b, .footer-contact__list a:hover svg { color: var(--accent); }
.footer-contact__list a:hover svg { translate: 2px -2px; }
.footer-contact__list a[download]:hover svg { translate: 0 2px; }
@media (max-width: 640px) { .footer-contact__go { width: 44px; height: 44px; } }
@media (prefers-reduced-motion: reduce) { .footer-contact__go, .footer-contact__go svg, .footer-contact__list svg { transition: none; } }
.site-footer__bar { padding: var(--sp-5) var(--gutter); border-top: 1px solid var(--line-soft); text-align: center; font-size: 13px; color: var(--fg-muted); }

.pill {
  display: inline-flex; align-items: center; gap: .45em; height: 2.5em; padding: 0 1em;
  border: 1.5px solid var(--fg-inactive); border-radius: var(--radius-pill);
  background: var(--bg); color: var(--fg); font-size: var(--pill-fs); line-height: 1; white-space: nowrap;
  -webkit-user-select: none; user-select: none; -webkit-user-drag: none; -webkit-touch-callout: none;
}
.pill svg { width: .9em; height: .9em; flex: none; }
.pill--lg { font-size: calc(var(--pill-fs) * 1.28); }
.pill--sm { font-size: calc(var(--pill-fs) * .8); }
.pill--fill { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.pill--contact {
  background: var(--c-accent); border-color: var(--c-accent); color: var(--c-white);
  transition: background-color .3s var(--ease), box-shadow .3s var(--ease), scale .35s cubic-bezier(.34, 1.56, .64, 1);
}
.pill--contact:hover, .pill--contact:focus-visible { background: #8f4dff; box-shadow: 0 0 0 .3em rgba(var(--c-accent-rgb), .28), 0 .6em 1.6em rgba(var(--c-accent-rgb), .45); scale: 1.04; }
.pill--contact:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.site-footer__stage.is-live { padding-bottom: clamp(16rem, 26vw, 30rem); }
.is-live .playground { position: absolute; inset: 0; display: block; padding: 0; pointer-events: none; }
.is-live .playground__list { display: block; }
.is-live .pill {
  position: absolute; left: 0; top: 0; z-index: 1; translate: 0 -200vh; will-change: translate, rotate; pointer-events: auto; touch-action: none; cursor: grab;
  transition: scale .3s var(--ease), box-shadow .3s var(--ease), background-color .3s var(--ease);
}
.is-live .pill--contact { z-index: 2; cursor: pointer; }
.is-live .pill.is-held { z-index: 20; cursor: grabbing; scale: 1.06; box-shadow: 0 1.2em 2.4em rgba(var(--c-navy-rgb), .22); }
.site-footer__stage.is-dragging { cursor: grabbing; }
.playground__tip {
  position: absolute; left: 0; top: 0; z-index: 30; padding: .75rem 1.1rem; border-radius: 14px;
  background: var(--c-navy); color: var(--c-white); font-size: var(--fs-body); line-height: 1.35; white-space: nowrap;
  box-shadow: 0 20px 50px rgba(var(--c-navy-rgb), .3); pointer-events: none; opacity: 0; transition: opacity .2s var(--ease);
}
.playground__tip small { display: block; margin-top: 2px; font-size: 13px; color: rgba(var(--c-light-rgb), .6); }
.playground__tip.is-on { opacity: 1; }
@media (max-width: 820px) {
  .site-footer__head { grid-template-columns: minmax(0, 1fr); grid-template-areas: "intro" "contact" "hint"; }
  .footer-contact { width: 100%; padding-top: 0; }
}
@media (max-width: 640px) {
  .pill[data-wide] { display: none; }
  .pill--lg { font-size: calc(var(--pill-fs) * 1.15); }
  .pill--sm { font-size: calc(var(--pill-fs) * .9); }
}
@media (prefers-reduced-motion: reduce) { .pill--contact { transition: none; } .pill--contact:hover, .pill--contact:focus-visible { scale: none; } }

/* ---- 20. Back to top -------------------------------------------------------- */
.to-top { position: fixed; right: var(--gutter); bottom: var(--gutter); z-index: var(--z-overlay); opacity: 0; transform: translateY(12px); pointer-events: none; }
.to-top.is-visible { opacity: 1; transform: none; pointer-events: auto; }
/* shown only to the logged-in admin (main.js), opposite the back-to-top button */
.admin-edit {
  position: fixed; left: var(--gutter); bottom: var(--gutter); z-index: var(--z-overlay);
  display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 18px 0 15px; border-radius: 999px;
  background: var(--c-accent); color: var(--c-white); font-size: 14px; font-weight: var(--fw-medium);
  box-shadow: 0 0 0 1px rgba(var(--c-white-rgb), .25), 0 10px 30px -10px rgba(var(--c-navy-rgb), .6); transition: background var(--dur-fast);
}
.admin-edit:hover, .admin-edit:focus-visible { background: var(--c-navy); }
.admin-edit svg { width: 17px; height: 17px; }

/* ---- 21. Lightbox -----------------------------------------------------------
   Full-screen viewer: counter and close on top, the image with its caption,
   arrows at the sides and a strip of neighbours (not on phones). The image
   grows out of its thumbnail and shrinks back on close (main.js). */
.lightbox {
  width: 100vw; max-width: none; height: 100vh; height: 100dvh; max-height: none; margin: 0; padding: var(--sp-5) var(--gutter) var(--sp-6);
  border: 0; background: transparent; color: var(--c-light); overflow: hidden;
}
.lightbox[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--sp-4); }
.lightbox::backdrop { background: rgba(5, 7, 12, .9); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-5); }
.lightbox__count { font-size: 14px; letter-spacing: .12em; color: rgba(var(--c-white-rgb), .55); font-variant-numeric: tabular-nums; }
.lightbox__count b { font-weight: var(--fw-medium); color: var(--c-white); }
.lightbox__fig { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 0; margin: 0; touch-action: pan-y; }
.lightbox__fig img {
  display: block; width: auto; height: auto; max-width: min(100%, 1100px); max-height: calc(100vh - 290px); max-height: calc(100dvh - 290px);
  object-fit: contain; background: #dadde7; box-shadow: 0 60px 120px -40px var(--c-black); transform-origin: 50% 50%;
}
.lightbox__cap { max-width: 60ch; margin-top: var(--sp-5); text-align: center; font-size: clamp(1rem, 1.4vw, 1.25rem); font-weight: var(--fw-light); color: var(--c-white); }
.lightbox__nav { position: absolute; top: 50%; translate: 0 -50%; z-index: 1; }
.lightbox__nav--prev { left: var(--gutter); } .lightbox__nav--next { right: var(--gutter); }
.lightbox__strip { display: flex; justify-content: center; gap: 8px; min-height: 48px; }
.lightbox__thumb { width: 64px; height: 48px; padding: 0; border: 0; border-radius: 3px; overflow: hidden; background: #dadde7; opacity: .35; cursor: pointer; transition: opacity .2s var(--ease); }
.lightbox__thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.lightbox__thumb:hover { opacity: .7; }
.lightbox__thumb.is-on { opacity: 1; outline: 2px solid var(--c-accent); outline-offset: 3px; }
.lightbox__thumb:focus-visible { opacity: 1; outline: 2px solid var(--c-white); outline-offset: 3px; }
.lightbox[open]::backdrop { animation: lb-fade .35s var(--ease) both; }
.lightbox[open] .lightbox__bar, .lightbox[open] .lightbox__nav, .lightbox[open] .lightbox__cap, .lightbox[open] .lightbox__strip { animation: lb-fade .4s var(--ease) .15s both; }
.lightbox.is-closing::backdrop, .lightbox.is-closing .lightbox__bar, .lightbox.is-closing .lightbox__nav, .lightbox.is-closing .lightbox__cap, .lightbox.is-closing .lightbox__strip { opacity: 0; transition: opacity .3s var(--ease); animation: none; }
@keyframes lb-fade { from { opacity: 0; } }
@media (max-width: 900px) { .lightbox__nav { top: auto; bottom: var(--sp-6); translate: none; } .lightbox__fig img { max-height: calc(100dvh - 240px); } }
@media (max-width: 640px) { .lightbox__strip { display: none; } .lightbox[open] { grid-template-rows: auto minmax(0, 1fr) 52px; } }
@media (prefers-reduced-motion: reduce) { .lightbox[open]::backdrop, .lightbox[open] .lightbox__bar, .lightbox[open] .lightbox__nav, .lightbox[open] .lightbox__cap, .lightbox[open] .lightbox__strip { animation: none; } }

/* ---- 22. Forms ---------------------------------------------------------------- */
.field { display: grid; gap: var(--sp-2); }
.field > label { font-size: var(--fs-small); font-weight: var(--fw-medium); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--fg-muted); }
.input, .textarea, .select {
  width: 100%; min-height: 56px; padding: var(--sp-4) 0; background: transparent; border: 0; border-radius: 0;
  border-bottom: var(--line-w) solid var(--line); color: var(--fg); font: inherit; font-size: var(--fs-nav);
  transition: border-color var(--dur-fast);
}
.input::placeholder, .textarea::placeholder { color: var(--fg-inactive); }
.input:focus, .textarea:focus, .select:focus { outline: none; border-bottom-color: var(--accent); }
.textarea { min-height: 140px; resize: vertical; }
.select { appearance: none; -webkit-appearance: none; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 14px) 50%, calc(100% - 8px) 50%; background-size: 6px 6px; background-repeat: no-repeat; padding-right: var(--sp-7); }
.check { display: inline-flex; align-items: center; gap: var(--sp-3); cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--c-accent); margin: 0; }
.field__error { font-size: var(--fs-small); color: #ff6b6b; }
.input[aria-invalid="true"] { border-bottom-color: #ff6b6b; }
