/* ── The three cards ─────────────────────────────────────────────────────────
   Built to the measurements of the reference Rupert gave: a #141414 card on
   #0B0B0B, one hairline border at 10% white, 20px radius, 22/20 padding, and a
   heading at 20px weight 500 rather than bold. One idea per card, stacked.

   What is ours rather than borrowed: the accent. Theirs is a product blue.
   Ours is the amber of a switchboard lamp, which is the thing this product
   actually replaces, and it means the two cannot be mistaken side by side.
   ────────────────────────────────────────────────────────────────────────── */

.cards3{
  position:relative;
  padding:clamp(60px,9vh,110px) 0;
  background:var(--ink);
  overflow:hidden;
}
/* The constellation runs behind everything in this section. It is decoration,
   so it never takes a pointer event and never gets read out. */
.stars{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;z-index:0;
}
.cards3__in{position:relative;z-index:1;}
.cards3__in{
  max-width:1180px;margin:0 auto;padding:0 var(--pad);
  display:grid;gap:14px;position:relative;z-index:1;
}
.cards3 h2{
  font:400 clamp(28px,4.4vw,46px)/1.06 var(--face);
  letter-spacing:-.03em;color:var(--white);
  max-width:16ch;margin-bottom:clamp(26px,3.4vw,44px);
}

.c3d{
  position:relative;
  background:rgba(20,20,20,.86);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.10);
  border-radius:20px;
  padding:22px 20px;
  overflow:hidden;
}
.c3d__h{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  margin-bottom:20px;
}
.c3d__h h3{
  font:500 20px/1.25 var(--ui);letter-spacing:-.2px;color:var(--white);
  /* 14ch turned nine words into four lines on a phone and shoved the
     constellation down into the list. It only needs to clear the + button. */
  max-width:22ch;margin:0;
}
.c3d__plus{
  width:34px;height:34px;flex:none;border-radius:50%;border:0;cursor:pointer;
  background:rgba(255,255,255,.07);color:rgba(255,255,255,.62);
  display:grid;place-content:center;font:300 19px/1 var(--ui);
  transition:background .2s ease,color .2s ease,transform .3s cubic-bezier(.4,0,.2,1);
}
.c3d__plus:hover{background:rgba(255,255,255,.13);color:#fff;}
.c3d.open .c3d__plus{transform:rotate(45deg);}
.c3d__more{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .42s cubic-bezier(.4,0,.2,1);
}
.c3d.open .c3d__more{grid-template-rows:1fr;}
.c3d__more > div{overflow:hidden;}
.c3d__more p{
  font:400 14.5px/1.6 var(--ui);color:rgba(255,255,255,.56);
  margin:18px 0 0;max-width:52ch;
}

/* ── 1. it learns as it goes ─────────────────────────────────────────────── */
/* A canvas, not an SVG now: it answers the cursor and grows as the list
   ticks. Full bleed to the card edges, because a constellation that stops
   short of the frame reads as a picture of one. */
.learn{position:relative;height:clamp(372px,72vw,410px);margin:0 -20px -22px;
  touch-action:pan-y;}
.learn__net{
  position:absolute;inset:0;width:100%;height:100%;display:block;
}
.learn__net line{stroke:rgba(255,255,255,.14);stroke-width:1;}
.learn__net circle{fill:var(--signal);}
.learn__net circle.dim{fill:rgba(255,255,255,.26);}
.learn__net .pulse{transform-box:fill-box;transform-origin:center;
  animation:node 3.6s ease-in-out infinite;}
@keyframes node{0%,100%{opacity:.35}50%{opacity:1}}

.learn__hub{
  position:absolute;left:50%;top:31%;transform:translate(-50%,-50%);
  pointer-events:none;
  width:76px;height:76px;border-radius:50%;
  background:#0B0B0B;border:1px solid rgba(255,255,255,.16);
  display:grid;place-content:center;
  font:600 21px/1 var(--face);letter-spacing:-.05em;color:var(--white);
  box-shadow:0 0 0 12px rgba(20,20,20,.92), 0 0 44px 8px rgba(255,255,255,.05);
}

.learn__list{
  position:absolute;left:14px;right:14px;bottom:14px;
  background:rgba(11,11,11,.90);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid rgba(255,255,255,.10);border-radius:14px;
  padding:12px 14px;list-style:none;margin:0;
}
.learn__list li{
  display:flex;align-items:center;gap:11px;padding:6px 0;
  font:400 13.5px/1.35 var(--ui);color:rgba(255,255,255,.44);
  transition:color .45s ease;
}
.learn__list li.done{color:var(--white);}
/* The one still open. Amber ring, nothing inside it, so it reads as a question
   rather than as a step that failed. */
.learn__list li.waiting{color:rgba(255,255,255,.72);}
.learn__list li.waiting .tick{border-color:rgba(159,255,0,.5);background:none;}
.learn__list li.waiting .tick svg{opacity:0;}
.tick{
  width:18px;height:18px;min-width:18px;min-height:18px;flex:0 0 18px;
  border-radius:50%;box-sizing:border-box;
  border:1.5px solid rgba(255,255,255,.24);
  display:inline-grid;place-items:center;
  transition:border-color .45s ease,background .45s ease;
}
.tick svg{width:11px;height:11px;display:block;opacity:0;transform:scale(.4);
  transition:opacity .3s ease,transform .4s cubic-bezier(.34,1.56,.64,1);}
.learn__list li.done .tick{border-color:var(--signal);background:var(--signal);}
.learn__list li.done .tick svg{opacity:1;transform:none;}

/* ── 2. the night log ────────────────────────────────────────────────────── */
.night3{position:relative;padding-left:62px;min-height:250px;}
.night3::before{
  content:"";position:absolute;left:52px;top:6px;bottom:6px;width:1px;
  background:rgba(255,255,255,.12);
}
.night3__run{
  content:"";position:absolute;left:52px;top:6px;width:1px;height:0;
  background:var(--signal);
  transition:height 2.4s cubic-bezier(.4,0,.2,1);
}
.cards3 .in .night3__run{height:calc(100% - 12px);}
.night3{list-style:none;margin:0;}
.night3 li{position:relative;padding:0 0 16px;list-style:none;}
.night3__t{
  position:absolute;left:-62px;width:44px;text-align:right;
  font:400 12px/1.5 var(--ui);color:rgba(255,255,255,.34);
  font-variant-numeric:tabular-nums;
}
.night3__d{
  position:absolute;left:-14px;top:6px;width:9px;height:9px;border-radius:50%;
  background:#141414;border:2px solid rgba(255,255,255,.24);
  transition:border-color .4s ease,background .4s ease;
}
.night3 li.lit .night3__d{background:var(--signal);border-color:var(--signal);}
.night3__row{
  background:rgba(255,255,255,.045);border-radius:12px;
  padding:11px 13px;display:flex;align-items:center;gap:11px;
  opacity:0;transform:translateX(-8px);
  transition:opacity .45s ease,transform .45s cubic-bezier(.4,0,.2,1);
}
.night3 li.lit .night3__row{opacity:1;transform:none;}
.night3__ic{
  width:30px;height:30px;flex:none;border-radius:8px;
  background:rgba(255,255,255,.07);
  display:grid;place-content:center;
}
.night3__ic svg{width:15px;height:15px;stroke:rgba(255,255,255,.66);
  fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
.night3 li.lit .night3__ic svg{stroke:var(--signal);}
.night3__b{min-width:0;}
.night3__b b{display:block;font:500 14px/1.3 var(--ui);color:var(--white);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.night3__b span{display:block;font:400 12.5px/1.3 var(--ui);
  color:rgba(255,255,255,.42);margin-top:2px;}

/* ── 3. what it plugs into ───────────────────────────────────────────────── */
/* Rows that drift, alternate directions, and fade out at both edges so the
   card looks like a window onto something larger rather than a finished list.
   Duplicated once in the markup so the loop has nothing to jump over. */
/* ⛔ The edges are faded with an overlay, not a mask.
   A mask clips everything the element paints, including the lift and the glow
   a tile throws on hover, so a tile you were pointing at came out with its
   corner sliced off. An overlay sits on top and clips nothing.

   The vertical padding is here for the same reason: overflow:hidden cuts at
   the padding box, so the lift needs somewhere to go. */
.tools3{
  position:relative;
  display:grid;gap:10px;
  margin:-12px -20px;padding:12px 20px;
  overflow:hidden;
}
.tools3::before,
.tools3::after{
  content:"";position:absolute;top:0;bottom:0;width:11%;
  pointer-events:none;z-index:2;
}
.tools3::before{
  left:0;
  background:linear-gradient(90deg,rgba(20,20,20,.92),rgba(20,20,20,0));
}
.tools3::after{
  right:0;
  background:linear-gradient(270deg,rgba(20,20,20,.92),rgba(20,20,20,0));
}
.tools3__row{padding:3px 0;}
.tools3__row{
  display:flex;gap:10px;width:max-content;
  animation:drift 42s linear infinite;
}
.tools3__row:nth-child(2){animation-duration:54s;animation-direction:reverse;}
.tools3__row:nth-child(3){animation-duration:48s;}
.tools3:hover .tools3__row{animation-play-state:paused;}
@keyframes drift{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* App icons, not line art. Each one on its own colour, the way they look on a
   phone home screen: the point of the row is that you recognise your own
   system at a glance, and a wall of identical grey outlines defeats that. */
.tool{
  width:60px;height:60px;flex:none;border-radius:15px;cursor:pointer;
  background:
    linear-gradient(160deg,
      color-mix(in srgb,var(--brand) 22%,transparent),
      color-mix(in srgb,var(--brand) 9%,transparent));
  border:1px solid color-mix(in srgb,var(--brand) 26%,transparent);
  display:grid;place-content:center;padding:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
  transition:transform .55s cubic-bezier(.22,.61,.36,1),
             box-shadow .55s ease,border-color .55s ease;
}
.tool--wide{width:auto;min-width:60px;padding:0 15px;}
.tool:hover,.tool.is-pinned{
  transform:translateY(-3px);
  border-color:color-mix(in srgb,var(--brand) 52%,transparent);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),
             0 8px 26px -8px color-mix(in srgb,var(--brand) 55%,transparent);
}

.tool svg{width:27px;height:27px;fill:var(--brand);display:block;}
/* The ones whose mark is genuinely more than one colour keep their own. */
.tool svg.multi{fill:none;}

.tool__w{
  font:600 12.5px/1.15 var(--ui);letter-spacing:-.02em;text-align:center;
  color:var(--brand);white-space:nowrap;
}

/* Built and working. A ring rather than another colour, because the colour is
   already saying which system it is. */
.tool--live{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),
             0 0 0 1px rgba(159,255,0,.34);
}

.tools3__say{
  grid-column:1/-1;margin:14px 0 0;min-height:34px;
  opacity:0;transform:translateY(4px);
  transition:opacity .5s ease,transform .5s cubic-bezier(.22,.61,.36,1);
}
.tools3__say.is-on{opacity:1;transform:none;}
.tools3__say b{
  display:block;font:600 12px/1.3 var(--ui);letter-spacing:.02em;
  color:var(--brand);
}
.tools3__say span{
  display:block;font:400 13px/1.45 var(--ui);color:rgba(255,255,255,.52);
  margin-top:2px;
}

@media (prefers-reduced-motion:reduce){
  .tools3__row{animation:none;}
  .tools3__row{animation:none;}
}

@media (min-width:900px){
  .cards3{padding:clamp(70px,10vh,120px) 0 clamp(50px,7vh,90px);}
  .cards3__in{grid-template-columns:repeat(3,1fr);align-items:stretch;gap:16px;}
  .cards3 h2{grid-column:1/-1;max-width:22ch;}
  /* Equal heights, and each card lays itself out so its device sits at the
     bottom on the same line as the others. Three cards of different heights is
     what made it look unfinished. */
  .c3d{padding:26px 24px;display:flex;flex-direction:column;min-height:520px;}
  .c3d__h{margin-bottom:22px;}
  .learn{height:340px;margin:auto -24px 0;}
  .night3{margin:auto 0 0;}
  /* Four rows on desktop, centred in whatever height is left, so the card is
     not two thirds empty above a grid pinned to the bottom. */
  .tools3{margin:auto -24px;padding:0 24px;}
  .tools3__row:nth-child(4){animation-duration:60s;animation-direction:reverse;}
}
@media (min-width:1200px){
  .c3d{min-height:560px;}
}
@media (max-width:420px){
  .tools3{grid-template-columns:repeat(4,1fr);}
  .learn__list{max-width:none;}
}
