/* ==========================================================================
   IFT LEARNINGS — 3D track carousel (home hero only)
   --------------------------------------------------------------------------
   Seven course cards on a rotating ring. Every card transform is written by
   carousel.js from a single fractional position, so a drag can land the ring
   half-way between two cards and everything stays consistent.

   This replaces the three.js particle field that used to fill the hero. That
   was 590 KB of third-party code for one decorative object; this is a few KB
   of CSS and JS, and it is the seven tracks — the thing the page is selling.

   Nothing here is required for the page to work. Without JS the cards fall
   back to a horizontal scroll-snap row (see the .no-js / reduced-motion
   blocks at the bottom), which is a perfectly good way to browse seven cards.
   ========================================================================== */

.c3d{
  --cw:clamp(178px,15.5vw,246px);          /* card width  */
  --ch:calc(var(--cw) * 1.267);            /* 600:760, the artwork's ratio */
  position:relative;
  min-width:0;                             /* see .hero-inner in site.css */
  display:flex;flex-direction:column;align-items:center;gap:1.6rem;
}

/* ── the ring ────────────────────────────────────────────────────────────── */
.c3d-stage{
  position:relative;width:100%;
  height:calc(var(--ch) + 3.4rem);
  perspective:1500px;
  perspective-origin:50% 46%;
  touch-action:pan-y;                      /* let vertical page scroll through */
  cursor:grab;
}
/* The ring is wider than its column. A card two steps round sits 303px from
   the centre of a 207px half-width stage, so without this it paints over the
   headline in the next column. overflow:hidden would cut it off with a hard
   vertical edge mid-card; a mask fades the tail into the background instead,
   which is also what the depth wants to look like. */
@supports ((mask-image:linear-gradient(#000,#000)) or (-webkit-mask-image:linear-gradient(#000,#000))){
  .c3d:not(.c3d-flat) .c3d-stage{
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 15%,#000 85%,transparent);
            mask-image:linear-gradient(90deg,transparent,#000 15%,#000 85%,transparent);
  }
}
.c3d-stage.dragging{cursor:grabbing}

/* Cards are centred by margin, not by a translate(-50%,-50%) baked into the
   transform — that keeps the transform JS writes purely three-dimensional and
   means a half-finished frame can never mis-centre the ring. */
.c3d-card{
  position:absolute;left:50%;top:50%;
  width:var(--cw);height:var(--ch);
  margin-left:calc(var(--cw) / -2);
  margin-top:calc(var(--ch) / -2);
  border-radius:18px;overflow:hidden;
  background:var(--panel);
  border:1px solid var(--line);
  transform-style:preserve-3d;
  backface-visibility:hidden;
  text-decoration:none;color:var(--fg);
  /* JS writes transform/opacity/z-index every frame, so neither may carry a
     transition — a transition here fights the rAF loop and the ring lags a
     frame behind the pointer during a drag. */
  box-shadow:0 26px 60px -28px rgba(0,0,0,.85);
  will-change:transform,opacity;
}
.c3d-card::after{                           /* accent hairline along the top */
  content:'';position:absolute;left:0;right:0;top:0;height:2px;
  background:var(--ca,var(--accent));opacity:.85;
}

/* Ring mode starts blank. The wrapper drops .c3d-flat before first paint (see
   partials/hero-carousel.blade.php), but carousel.js does not run until the
   document has parsed — without this the seven cards would sit stacked on the
   centre point, fully opaque, for every frame in between. JS writes opacity as
   an inline style, which outranks this. */
.c3d:not(.c3d-flat) .c3d-card{opacity:0}

.c3d-art{position:absolute;inset:0;display:block}
.c3d-art img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--ease);
}
.c3d-card.is-active .c3d-art img{transform:scale(1.05)}

.c3d-body{
  position:absolute;inset:auto 0 0 0;z-index:2;
  padding:0 1.05rem 1.15rem;
  display:flex;flex-direction:column;align-items:flex-start;gap:.42rem;
}
/* The artwork carries its own vignette, but a bright scene — the SEO bars, the
   AI nodes — still reads through it behind the track name. This scrim sits
   between the two and is sized to the text block rather than to the card. */
.c3d-body::before{
  content:'';position:absolute;inset:-3.4rem 0 0 0;z-index:-1;pointer-events:none;
  background:linear-gradient(to top,#0B0306 6%,rgba(11,3,6,.88) 42%,rgba(11,3,6,0));
}
.c3d-num{
  font-family:var(--font-m);font-size:9.5px;letter-spacing:.24em;
  color:var(--ca,var(--accent));
}
.c3d-tier{
  position:absolute;top:.95rem;right:.95rem;z-index:2;
  font-size:8.5px;letter-spacing:.2em;text-transform:uppercase;
  padding:.34em .62em;border-radius:99px;
  color:var(--accent-2);border:1px solid rgba(255,194,75,.42);
  background:rgba(14,4,7,.55);backdrop-filter:blur(4px);
}
.c3d-name{
  font-family:var(--font-d);font-weight:800;text-transform:uppercase;
  font-size:clamp(.92rem,1.32vw,1.16rem);line-height:1.05;letter-spacing:-.01em;
  text-wrap:balance;
}
.c3d-meta{
  font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
}
.c3d-go{
  margin-top:.5rem;font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ca,var(--accent));
  opacity:0;transform:translateY(6px);
  transition:opacity .45s var(--ease),transform .45s var(--ease);
}
.c3d-card.is-active .c3d-go{opacity:1;transform:none}

/* Only the front card is a live target. Without this the invisible cards
   behind it still swallow clicks and drags aimed at the one on top. */
.c3d-card{pointer-events:none}
.c3d-card.is-active{pointer-events:auto}
.c3d-card.is-active{border-color:color-mix(in srgb,var(--ca,var(--accent)) 46%,transparent)}
@supports not (background:color-mix(in srgb,red,blue)){
  .c3d-card.is-active{border-color:var(--line-2)}
}

/* ── controls ────────────────────────────────────────────────────────────── */
.c3d-ui{display:flex;align-items:center;gap:1.15rem}
.c3d-nav{
  width:38px;height:38px;border-radius:50%;flex:0 0 auto;
  border:1px solid var(--line-2);background:transparent;color:var(--fg);
  font-size:15px;line-height:1;cursor:pointer;
  display:grid;place-items:center;
  transition:border-color .3s var(--ease),background .3s var(--ease),color .3s var(--ease);
}
.c3d-nav:hover,.c3d-nav:focus-visible{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.c3d-dots{display:flex;gap:7px}
.c3d-dot{
  width:7px;height:7px;padding:0;border-radius:50%;cursor:pointer;
  border:1px solid var(--line-2);background:transparent;
  transition:background .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease);
}
.c3d-dot[aria-selected="true"]{
  background:var(--dc,var(--accent));border-color:var(--dc,var(--accent));transform:scale(1.42);
}
/* A 7px dot is far below the 24px minimum for a touch target, so each dot
   carries an invisible pad that is comfortably tappable. */
.c3d-dot::before{content:'';position:absolute;inset:-9px}
.c3d-dot{position:relative}

.c3d-live{
  position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;
}

@media(max-width:1100px){
  .c3d{--cw:clamp(184px,29vw,232px)}
}
/* 58vw put the neighbouring cards 235px from the centre of a 179px half-width
   stage, so the coverflow was mostly behind the edge mask rather than peeking
   out from behind the front card. 50vw keeps the overhang inside the fade. */
@media(max-width:520px){
  .c3d{--cw:min(50vw,190px);gap:1.1rem}
  .c3d-stage{height:calc(var(--ch) + 2.6rem)}
}

/* ── no JS, or reduced motion: a plain snap row ─────────────────────────────
   .c3d-flat is set by carousel.js when it bails out, and is also the state a
   page with JS disabled is left in, because the ring only exists once JS has
   written the first set of transforms. */
.c3d-flat .c3d-stage{
  height:auto;perspective:none;cursor:auto;
  display:flex;gap:1rem;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;padding-bottom:1rem;
}
.c3d-flat .c3d-card{
  position:relative;left:auto;top:auto;margin:0;flex:0 0 auto;
  transform:none!important;opacity:1!important;pointer-events:auto;
  scroll-snap-align:center;
}
.c3d-flat .c3d-go,.c3d-flat .c3d-art img{opacity:1;transform:none}
.c3d-flat .c3d-ui{display:none}

@media(prefers-reduced-motion:reduce){
  .c3d-art img,.c3d-go{transition:none}
}
