/* ==========================================================================
   news.css — News timeline layout, date markers & highlight styling
   --------------------------------------------------------------------------
   Depends on css/variables.css for design tokens (--brand, --brand-accent,
   --muted, --text, --panel, --ring, radii, spacing, easings).

   Scope (Task 11.3):
     - Vertical timeline layout with a continuous connecting line on the
       LEFT and a dot marker per item sitting ON that line.   (Req 6.1)
     - A month/year date marker styled beside each item.       (Req 6.1)
     - Highlighted items (`.news-highlight`) get a contrasting accent border
       and a subtle background gradient distinct from standard items. (Req 6.3)
     - The news-specific slide-and-fade reveal transition (<= 500ms),
       scoped to `.reveal-news` inside the timeline.           (Req 6.2 support)

   DOM (index.html + js/news.js):
     aside#news.card
       └ div#news-list.news-timeline
           └ article.news-item.reveal.reveal-news[data-date="YYYY-MM"]
               ├ span.news-marker[aria-hidden]   (inserted by news.js)
               ├ div.title
               ├ div.meta.muted > time
               └ p
       └ p#news-empty.empty-state[hidden]

   Highlighted items add `.news-highlight`; news.js reorders items into
   reverse-chronological order and toggles the empty-state placeholder.

   CONTRAST NOTE (Req 9.5)
   --------------------------------------------------------------------------
   The connecting line, the dot markers and the highlight accent are all
   DECORATIVE (non-text) uses of --brand / the warm accent, so the brand-on-
   card text ratio does not apply. The date-marker TEXT uses --muted, which
   meets AA on the --card surface in both themes (dark 4.97:1, light 4.75:1).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Timeline-scoped tokens
   --------------------------------------------------------------------------
   The highlight accent is a WARM amber, deliberately distinct from both the
   cool --brand blue used for the standard line/markers and from the plain
   (accent-free) standard items — echoing the site's original orange
   highlight while staying legible in both themes. Tints/borders are authored
   as explicit rgba values (no color-mix) for maximum browser support.
   -------------------------------------------------------------------------- */
.news-timeline {
  --news-accent: #f5a623;                  /* warm amber highlight accent    */
  --news-accent-tint: rgba(245, 166, 35, 0.12);
  --news-accent-border: rgba(245, 166, 35, 0.55);

  /* Rail geometry — kept in one place so the line and the dot stay aligned.
     Container reserves `--rail` px of left padding; the line is centered on
     x = --rail-center; each dot is pulled back onto that center.            */
  --rail: 28px;
  --rail-center: 7px;
  --dot-size: 14px;
}

/* Deeper amber on the light surface (still decorative, not text). */
:root.light .news-timeline {
  --news-accent: #c2410c;
  --news-accent-tint: rgba(194, 65, 12, 0.10);
  --news-accent-border: rgba(194, 65, 12, 0.50);
}

/* --------------------------------------------------------------------------
   Timeline container + continuous connecting line (Req 6.1)
   --------------------------------------------------------------------------
   `padding-left: var(--rail)` reserves the rail so item boxes never overlap
   the line (keeping it continuous even behind a highlighted item). The line
   is a single ::before spanning the full height; its ends fade to transparent
   so the overhang above the first / below the last dot reads as intentional.
   -------------------------------------------------------------------------- */
.news-timeline {
  position: relative;
  padding-left: var(--rail);

  /* Cap height so a growing news list scrolls instead of stretching the page:
     ~600px, but never more than 80% of the viewport on short screens. */
  max-height: min(600px, 80vh);
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: var(--space-1);      /* clearance so items clear the scrollbar */
  -webkit-overflow-scrolling: touch;

  /* Thin themed scrollbar (Firefox). */
  scrollbar-width: thin;
  scrollbar-color: var(--brand) transparent;

  /* Connecting line drawn as a background (NOT ::before) so it scrolls WITH the
     items and stays aligned with the dots. `local` binds the background to the
     scrollable content; a small repeated solid tile covers the full content
     height regardless of scroll. */
  background-image: linear-gradient(var(--brand), var(--brand));
  background-repeat: repeat-y;
  background-size: 2px 8px;
  background-position: calc(var(--rail-center) - 1px) 0;
  background-attachment: local;
}

.news-timeline::-webkit-scrollbar { width: 6px; }
.news-timeline::-webkit-scrollbar-track { background: transparent; }
.news-timeline::-webkit-scrollbar-thumb {
  background: var(--brand);
  border-radius: var(--radius-pill);
}

/* Respect the empty-state toggle set by news.js (hidden attribute wins). */
.news-timeline[hidden] {
  display: none;
}

/* --------------------------------------------------------------------------
   News items
   --------------------------------------------------------------------------
   Items are indented to the right of the rail (via the container padding).
   A little inner padding + rounded corners give the highlight treatment room
   without shifting standard items (the highlight uses box-shadow, not border,
   so it never changes the box geometry or the dot alignment).
   -------------------------------------------------------------------------- */
.news-item {
  position: relative;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
}

.news-item + .news-item {
  margin-top: var(--space-2);
}

/* --------------------------------------------------------------------------
   Dot marker — sits ON the connecting line (Req 6.1)
   --------------------------------------------------------------------------
   Absolutely positioned from the item's padding edge and pulled left by the
   full rail width so its centre lands on --rail-center. A soft --ring halo
   separates the dot from the line on any card surface (no dependency on the
   exact card background colour).
   -------------------------------------------------------------------------- */
.news-marker {
  position: absolute;
  left: calc(-1 * var(--rail));
  top: calc(var(--space-1) + 0.4rem);
  width: var(--dot-size);
  height: var(--dot-size);
  /* centre the dot on the rail centre: shift by (rail-center - dot/2) */
  margin-left: calc(var(--rail-center) - (var(--dot-size) / 2));
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 3px var(--ring);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Date marker (Req 6.1) — the month/year beside each item
   --------------------------------------------------------------------------
   Styled as a compact uppercase label. --muted keeps AA contrast on the card
   in both themes (see contrast note above).
   -------------------------------------------------------------------------- */
.news-item .title {
  font-size: 1rem;
  line-height: 1.35;
}

.news-item .meta {
  margin-top: 2px;
}

.news-item .meta time {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.news-item p {
  margin-top: var(--space-1);
  color: var(--text);
}

/* --------------------------------------------------------------------------
   Highlighted items (Req 6.3)
   --------------------------------------------------------------------------
   Distinct from standard items via: a warm accent edge + a full 1px accent
   ring (both via inset box-shadow, so no layout shift), and a subtle diagonal
   background gradient. The dot also switches to the accent colour.
   -------------------------------------------------------------------------- */
.news-item.news-highlight {
  background-image: linear-gradient(
    135deg,
    var(--news-accent-tint),
    transparent 60%
  );
  box-shadow:
    inset 4px 0 0 0 var(--news-accent),          /* accent left edge        */
    inset 0 0 0 1px var(--news-accent-border);   /* subtle full accent ring */
}

.news-item.news-highlight .news-marker {
  background: var(--news-accent);
  box-shadow: 0 0 0 4px var(--news-accent-tint);
}

/* --------------------------------------------------------------------------
   Empty-state placeholder (Req 6.5) — shown by news.js when there are no items
   -------------------------------------------------------------------------- */
#news-empty {
  margin-top: var(--space-1);
  color: var(--muted);
  font-style: italic;
}

/* ==========================================================================
   Slide-and-fade reveal (Req 6.2 support)
   --------------------------------------------------------------------------
   News items reveal with a horizontal slide-and-fade rather than the default
   fade-up. The hidden initial state is gated on `html.js-loaded` so that with
   no JS (or if scripts fail) every item renders in its final visible state
   (Req 9.6). The rules are scoped under `.news-timeline` so their specificity
   beats the generic `.reveal` hide rules in animations.css regardless of
   stylesheet load order, ensuring the news slide (not the default translateY)
   wins for items carrying both classes.

   The shared IntersectionObserver (threshold 0.1) adds `.visible`; the 420ms
   transition completes well within the 500ms budget.
   ========================================================================== */
html.js-loaded .news-timeline .reveal-news {
  opacity: 0;
  transform: translateX(-18px);
  transition:
    opacity 420ms var(--ease-out),
    transform 420ms var(--ease-out);
  will-change: opacity, transform;
}

html.js-loaded .news-timeline .reveal-news.visible {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   Reduced motion (Req 3.4 / 8.5) — render the final state instantly, no
   transform/opacity animation.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.js-loaded .news-timeline .reveal-news,
  html.js-loaded .news-timeline .reveal-news.visible {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
