/* ─────────────────────────────────────────────────────────────────────────
   jt-projects.css - the case archive, dressed as tape.

   The page already called itself an archive: "case archive · shelf 04",
   "twelve tapes off the shelf", a reel spinning on every card, "N tapes" on
   every group. Nothing here invents a metaphor; it finishes the one the copy
   was already using.

   Note what is NOT here: the stat figures are strings - "10L+", "Dozens",
   "Same-day", "per industry" - so there are no meters, no bars and no
   percentages. A bar length would be a magnitude nobody supplied. They stay
   readouts and show exactly what was written.

   Motion hangs off [data-lit], set once per card by jt-reveal.js.

   The card is .jt-cassette, not .jt-tape: jt-services.css already uses
   .jt-tape for the punched paper tape in its process strip. Two different
   objects under one name is a trap the moment both files meet on one page.
   ───────────────────────────────────────────────────────────────────────── */

/* ══ the shell ═════════════════════════════════════════════════════════ */

.jt-shell {
  position: relative;
  display: block;
  width: 100%;
  padding: 11px 14px 13px;
  border: 0;
  border-bottom: 2px solid var(--jt-navy);
  background: linear-gradient(178deg, #0A0E14 0%, #05070A 60%, #0B1017 100%);
  text-align: left;
  cursor: pointer;
  user-select: none;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}
.jt-shell:focus-visible { outline: 3px solid var(--jt-primary-screen); outline-offset: -3px; }
.jt-shell-lines {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* grain over scanlines - both, the way every other screen on the site is
     built. Scanlines alone read as stripes; the phosphor dots are what make it
     a tube. Same 3px pitch and colour used on the landing monitors. */
  background-image:
    radial-gradient(rgba(120, 150, 190, 0.26) 0.8px, transparent 0.9px),
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 0 1px, transparent 1px 3px);
  background-size: 3px 3px, auto;
  opacity: 0.5;
}

.jt-shell-top {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
}
.jt-shell-side {
  flex: 0 0 auto;
  padding: 2px 6px;
  border: 1px solid rgba(160, 180, 210, 0.35);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #8E9AAC;
}
.jt-shell-sector {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-screen), var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8E9AAC;
}

/* the mechanical counter: three drums behind one window */
.jt-counter {
  flex: 0 0 auto;
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: 2px;
  background: #1A1F27;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.85), 0 1px 0 rgba(255, 255, 255, 0.08);
}
.jt-counter b {
  display: block;
  width: 13px;
  padding: 2px 0;
  border-radius: 1px;
  background: linear-gradient(180deg, #EFE9D8, #C9C1AC);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  text-align: center;
  color: #16202B;
  /* the seam where two drums meet */
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

.jt-shell-mark {
  flex: 0 0 auto;
  width: 19px;
  height: 19px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid rgba(160, 180, 210, 0.4);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1;
  color: #C9C4B6;
}

/* ── the reels ─────────────────────────────────────────────────────────
   Two hubs with the tape between them. The left one is the supply reel and
   runs full; the right is the take-up and runs near empty, which is what tells
   you which way the tape is travelling. */

.jt-reels {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0;
  margin: 11px 0 10px;
  /* Capped, and not stretched across the card. Hubs pushed to opposite ends of
     a 640px header read as a progress bar; a cassette's two hubs sit close
     together with a short run of tape showing between them. */
  max-width: 230px;
}
.jt-hub {
  position: relative;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #05070A 0 26%, transparent 27%),
    conic-gradient(from 0deg, #2A2F36 0 12deg, #171C22 12deg 24deg);
  box-shadow: inset 0 0 0 2px #3A4250, inset 0 0 8px rgba(0, 0, 0, 0.9);
  animation: jt-reel 3.4s linear infinite;
}
/* how much tape is wound on: a ring, thick on the supply side, thin on take-up */
.jt-hub-full { box-shadow: inset 0 0 0 2px #3A4250, inset 0 0 0 11px #14181E, inset 0 0 8px rgba(0, 0, 0, 0.9); }
.jt-hub-take { box-shadow: inset 0 0 0 2px #3A4250, inset 0 0 0 2px #14181E, inset 0 0 8px rgba(0, 0, 0, 0.9); }
/* the hub teeth */
.jt-hub i {
  position: absolute;
  inset: 34%;
  border-radius: 50%;
  background: #0A0E14;
  box-shadow: inset 0 0 0 1.5px #4A5464;
}
@keyframes jt-reel { to { transform: rotate(360deg); } }

/* the exposed tape between the hubs */
.jt-web {
  flex: 1 1 auto;
  height: 14px;
  margin: 0 -3px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.09) 0 1px, transparent 1px),
    linear-gradient(180deg, #241C16, #1A1410);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.7);
}

.jt-shell-title {
  position: relative;
  z-index: 2;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 19px;
  line-height: 1.14;
  text-transform: uppercase;
  color: #E7E1D0;
}

/* a closed tape stops its reels - nothing is playing */
.jt-cassette:has(.jt-file-body[data-open="0"]) .jt-hub { animation-play-state: paused; }

/* ══ collapse ══════════════════════════════════════════════════════════ */

.jt-file-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.34s cubic-bezier(0.22, 0.9, 0.25, 1);
}
.jt-file-body > div { min-height: 0; overflow: hidden; }
.jt-file-body[data-open="0"] { grid-template-rows: 0fr; }

/* ══ the J-card insert ═════════════════════════════════════════════════ */
/* PROBLEM / BUILT / CHANGED are the three things printed on the paper that
   comes folded inside the case, so they are set on ruled stock with the red
   spine stripe running down the fold. */

.jt-jrow {
  position: relative;
  padding-left: 13px;
}
.jt-jrow::before {
  content: "";
  position: absolute;
  left: 0;
  top: 3px;
  bottom: 3px;
  width: 3px;
  border-radius: 1px;
  background: rgba(222, 50, 38, 0.28);
}
.jt-jrow + .jt-jrow { border-top: 1px dashed rgba(0, 35, 73, 0.16); padding-top: 11px; }

/* ══ the readout ═══════════════════════════════════════════════════════ */
/* A bezel and engraved labels. The figures are shown exactly as written -
   several of them are words, not numbers. */

.jt-readout {
  position: relative;
  box-shadow: inset 0 0 0 2px #1A1F27, inset 0 0 22px rgba(0, 0, 0, 0.9);
}
.jt-readout::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.42;
  background-image:
    radial-gradient(rgba(120, 150, 190, 0.26) 0.8px, transparent 0.9px),
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 0 1px, transparent 1px 3px);
  background-size: 3px 3px, auto;
}
.jt-readout-cell {
  position: relative;
  z-index: 1;
  background: linear-gradient(180deg, rgba(125, 227, 154, 0.05), transparent 60%);
}
.jt-readout-cell + .jt-readout-cell { box-shadow: inset 1px 0 0 rgba(160, 180, 210, 0.14); }
/* the figures come up as the card is revealed, left to right */
.jt-readout-cell > div:first-child {
  opacity: 0;
  transform: translateY(5px);
  transition: opacity 0.45s linear, transform 0.45s cubic-bezier(0.2, 0.9, 0.25, 1);
}
[data-lit] .jt-readout-cell > div:first-child { opacity: 1; transform: none; }
.jt-readout-cell:nth-child(2) > div:first-child { transition-delay: 0.1s; }
.jt-readout-cell:nth-child(3) > div:first-child { transition-delay: 0.2s; }

/* ══ stack chips: keycaps ══════════════════════════════════════════════ */
/* the same moulded cap the hero board and the Services rack use */

.jt-key {
  padding: 5px 9px 6px !important;
  border: 0 !important;
  border-radius: 3px !important;
  background: linear-gradient(180deg, #F5F0E2, #E2DBC8) !important;
  box-shadow:
    inset 0 -3px 0 #C9C1AC,
    inset 2px 0 0 rgba(255, 255, 255, 0.34),
    inset 0 2px 0 rgba(255, 255, 255, 0.62),
    inset 0 0 0 1px rgba(0, 0, 0, 0.14),
    0 2px 0 #C9C1AC,
    0 4px 0 rgba(0, 35, 73, 0.36);
  transition: transform 0.09s ease-out, box-shadow 0.09s ease-out;
}
.jt-key:hover {
  transform: translateY(2px);
  box-shadow:
    inset 0 -2px 0 #C9C1AC,
    inset 2px 0 0 rgba(255, 255, 255, 0.34),
    inset 0 2px 0 rgba(255, 255, 255, 0.62),
    inset 0 0 0 1px rgba(0, 0, 0, 0.14),
    0 1px 0 #C9C1AC,
    0 2px 0 rgba(0, 35, 73, 0.36);
}

/* ══ the shelf rail ════════════════════════════════════════════════════ */

.jt-shelf-rail {
  position: relative;
  padding-left: 10px !important;
}
.jt-shelf-rail::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1px;
  bottom: 12px;
  width: 4px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--kb-red), rgba(222, 50, 38, 0.35));
}

/* ══ the filter deck ═══════════════════════════════════════════════════ */
/* These chips were briefly moulded deck buttons, which made this page the only
   one whose chips did not look like everyone else's. Services, Industries and
   Technologies all use the same part: a 2px navy outline over a hard 3px
   offset shadow, pressed flat and turned red on interaction. The markup
   already carries that; all this adds is the hover the other pages get from a
   style-hover attribute the filter chips never had. */

.jt-transport:hover {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--jt-navy) !important;
  background: var(--kb-red) !important;
  color: #FFF !important;
}
.jt-transport:focus-visible {
  outline: 2px solid var(--jt-navy);
  outline-offset: 3px;
}

/* ══ reduced motion ════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .jt-hub { animation: none; }
  .jt-file-body { transition: none; }
  .jt-readout-cell > div:first-child { opacity: 1; transform: none; transition: none; }
}

/* ══ narrow screens ════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .jt-shell { padding: 10px 12px 12px; }
  .jt-hub { width: 32px; height: 32px; }
  .jt-reels { max-width: 190px; }
  .jt-shell-title { font-size: 17px; }
  .jt-counter b { width: 12px; font-size: 10px; }
}
