/* ==========================================================================
   COMPONENT — .c-timeline / .c-entry
   The video index, read as a dated timeline.

   Every entry is a full-width row split in half down the centre: the frame on
   one side, the writing on the other. Consecutive rows SWAP those halves —
   video left / text right, then text left / video right — so the eye is
   handed back and forth down the page instead of tracking one rigid column.

   Every frame is identical in size. A record of 660 uploads should not have
   some rows shouting louder than others; the alternation does the work that
   varying sizes were doing badly.

   Sides come from :nth-child, so the rhythm survives sorting, filtering and
   searching — the script re-appends the visible set in order and the pattern
   re-forms on whatever is actually on screen.

   WP Phase 2 targets:
     template-parts/archive/timeline.php
     template-parts/card/entry-video.php
   ========================================================================== */

.c-timeline {
  position: relative;
  --col: calc((100% - 11 * var(--gutter)) / 12);
}

/* The spine runs down the gutter between the two halves. Drawn on the
   container, not per-entry, so filtering can never leave a gap or a stub. */
.c-timeline::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 50%;
  inline-size: var(--bw-hair);
  background: var(--c-line);
  transform: translateX(-50%);
  pointer-events: none;
}

.c-entry { display: block; }
.c-entry[hidden] { display: none; }

.c-entry__link {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: center;
  padding-block: var(--sp-6);
  border-block-end: var(--bw-hair) solid var(--c-line);
}

.c-entry:last-of-type .c-entry__link { border-block-end: 0; }

/* --------------------------------------------------------------------------
   THE SWAP
   Odd  — frame on the left  (1-6),  writing on the right (7-12)
   Even — writing on the left (1-6), frame on the right  (7-12)
   -------------------------------------------------------------------------- */

.c-entry:nth-child(odd) .c-entry__media { grid-row: 1; grid-column: 1 / span 6; }
.c-entry:nth-child(odd) .c-entry__text  { grid-row: 1; grid-column: 7 / span 6; padding-inline-start: var(--sp-6); }

.c-entry:nth-child(even) .c-entry__media { grid-row: 1; grid-column: 7 / span 6; }
.c-entry:nth-child(even) .c-entry__text  { grid-row: 1; grid-column: 1 / span 6; padding-inline-end: var(--sp-6); }

/* The writing is capped to a readable measure, so on an even row it would
   otherwise sit against the page edge with a void beside the spine. Push it
   across: the column mirrors, the text alignment does not. */
.c-entry__text > * { max-inline-size: none; }
.c-entry:nth-child(even) .c-entry__text > * { margin-inline-start: auto; }

/* The node marks the row on the spine, vertically centred on the frame. */
.c-entry__node {
  grid-row: 1;
  grid-column: 1 / -1;
  justify-self: center;
  align-self: center;
  inline-size: 9px;
  block-size: 9px;
  border-radius: var(--radius-pill);
  background: var(--c-bg);
  border: var(--bw-rule) solid var(--c-line-strong);
  pointer-events: none;
  transition:
    border-color var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.c-entry__link:hover .c-entry__node,
.c-entry__link:focus-visible .c-entry__node {
  border-color: var(--c-accent);
  background: var(--c-accent);
  transform: scale(1.4);
}

/* --------------------------------------------------------------------------
   THE FRAME — identical for every entry, whichever side it lands on.
   -------------------------------------------------------------------------- */

.c-entry__media {
  position: relative;
  aspect-ratio: var(--ar-wide);
  overflow: hidden;
  background: var(--slate-900);
  outline: var(--bw-hair) solid transparent;
  transition: outline-color var(--dur-base) var(--ease-out);
}

.c-entry__link:hover .c-entry__media,
.c-entry__link:focus-visible .c-entry__media { outline-color: var(--c-accent); }

.c-entry__image {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1.001);
  transition: transform var(--dur-slow) var(--ease-out), filter var(--dur-base) var(--ease-out);
}

.c-entry__link:hover .c-entry__image,
.c-entry__link:focus-visible .c-entry__image { transform: scale(1.05); filter: brightness(0.88); }

.c-entry__duration {
  position: absolute;
  inset-block-end: var(--sp-3);
  inset-inline-end: var(--sp-3);
  padding: 0.15rem var(--sp-2);
  background: color-mix(in oklab, #0A0E10 82%, transparent);
  backdrop-filter: blur(4px);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tr-mono);
  color: var(--stone-50);
  line-height: 1.5;
}

.c-entry__play {
  position: absolute;
  inset-block-end: var(--sp-3);
  inset-inline-start: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.3rem var(--sp-4);
  background: var(--c-accent);
  color: var(--c-accent-on);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  line-height: 1.5;
  transform: translateX(-101%);
  transition: transform var(--dur-base) var(--ease-out);
}

.c-entry__link:hover .c-entry__play,
.c-entry__link:focus-visible .c-entry__play { transform: none; }

.c-entry__play svg { inline-size: 0.55em; block-size: auto; }

/* --------------------------------------------------------------------------
   THE WRITING — always left-aligned. Mirroring the text as well as the frame
   would trade legibility for symmetry, and the frame already carries the swap.
   -------------------------------------------------------------------------- */

.c-entry__stamp {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin-block-end: var(--sp-4);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--c-ink-muted);
  line-height: 1;
}

.c-entry__stamp b { font-weight: var(--fw-medium); color: var(--c-ink); }
.c-entry__no { color: var(--c-accent-text); }

.c-entry__stamp::after {
  content: "";
  flex: 1;
  block-size: var(--bw-hair);
  background: var(--c-line);
}

.c-entry__topic {
  display: inline-block;
  margin-block-end: var(--sp-3);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--c-ink-muted);
}

.c-entry__title {
  font-family: var(--ff-display);
  font-optical-sizing: auto;
  font-variation-settings: "SOFT" 0, "WONK" 0;
  font-weight: var(--fw-regular);
  font-size: var(--fs-lg);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
  color: var(--c-ink);
  /* A YouTube title is third-party text of any length. It gets ONE line;
     the full string stays in data-title and on the link itself. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.c-entry__title span {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.c-entry__title span {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% var(--bw-hair);
  transition: background-size var(--dur-base) var(--ease-out);
  padding-block-end: 0.06em;
}

.c-entry__link:hover .c-entry__title span,
.c-entry__link:focus-visible .c-entry__title span { background-size: 100% var(--bw-hair); }

.c-entry__dek {
  margin-block-start: var(--sp-4);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.c-entry__foot {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-block-start: var(--sp-5);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--c-ink-muted);
  line-height: 1;
}

.c-entry__foot svg {
  inline-size: 1.5rem;
  block-size: auto;
  color: var(--c-accent-text);
  transition: transform var(--dur-base) var(--ease-out);
}

.c-entry__link:hover .c-entry__foot svg { transform: translateX(0.35rem); }

/* --------------------------------------------------------------------------
   RESPONSIVE — the halves stop alternating and stack.
   -------------------------------------------------------------------------- */

@media (max-width: 60rem) {
  .c-timeline::before { display: none; }
  .c-entry__node { display: none; }

  .c-entry__link {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--sp-5);
    padding-block: var(--sp-6);
    align-items: start;
  }

  .c-entry:nth-child(odd) .c-entry__media,
  .c-entry:nth-child(even) .c-entry__media { grid-row: 1; grid-column: 1 / -1; }

  .c-entry:nth-child(odd) .c-entry__text,
  .c-entry:nth-child(even) .c-entry__text {
    grid-row: 2;
    grid-column: 1 / -1;
    padding-inline: 0;
  }

  .c-entry__title { font-size: var(--fs-lg); }
}

/* Long archives: skip laying out offscreen entries entirely. */
@supports (content-visibility: auto) {
  .c-entry {
    content-visibility: auto;
    contain-intrinsic-size: auto 320px;
  }
}

/* --------------------------------------------------------------------------
   Reorder reveal — capped by the script, so cost never scales with N.
   -------------------------------------------------------------------------- */

.c-timeline[data-reordered] > .c-entry[style*="--reveal-i"] {
  animation: entry-reveal var(--dur-base) var(--ease-out) both;
  animation-delay: calc(var(--reveal-i, 0) * 22ms);
}

@keyframes entry-reveal {
  from { opacity: 0; transform: translateY(0.6rem); }
  to   { opacity: 1; transform: none; }
}


/* --------------------------------------------------------------------------
   TOUCH: the play chip

   The chip is parked at translateX(-101%) and slides in on hover. There is
   no hover on a touch screen, so on a phone it sat permanently off the left
   edge of its card — present in the layout, invisible to the reader, and
   measured at -56px.

   Keyed on the POINTER, not the viewport width: a small window on a laptop
   still has a cursor and should still get the slide.
   -------------------------------------------------------------------------- */

@media (hover: none) {
  .c-entry__play {
    position: static;
    transform: none;
    inline-size: fit-content;
    margin-block-start: var(--sp-4);
    padding-block: var(--sp-2);
  }
}

/* --------------------------------------------------------------------------
   PHONE: the title and dek wrap rather than truncate

   One line is right on a wide screen — a full line holds the whole title, so
   nothing is lost. At 375px a line holds about thirty characters, and
   "10 Things You Should AVOID Doing in Malta" became "10 Things You Should
   AVOID…". That is a worse read than two lines, and the no-wrap rule was
   about layouts that looked broken, not about hiding what a video is called.

   Two lines, hard ceiling: a long title still cannot push a card out of shape.
   -------------------------------------------------------------------------- */

@media (max-width: 44rem) {
  .c-entry__title,
  .c-entry__title span,
  .c-entry__dek {
  white-space: normal;
  text-wrap: pretty;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  }
}
